无符号字符值循环 C++
Posted
技术标签:
【中文标题】无符号字符值循环 C++【英文标题】:Unsigned char value cycle C++ 【发布时间】:2021-10-04 13:02:33 【问题描述】:我(想我)理解不同变量类型的数学是如何工作的。例如,如果我超过了 unsigned int
变量的最大限制,它将循环回到 0
。
我不明白unsigned char
这段代码的行为:
#include<iostream>
int main()
unsigned char var 0 ;
for(int i = 0; i < 501; ++i)
var += 1;
std::cout << var << '\n';
这只是输出1...9
,然后是一些符号和大写字母,然后它什么都不打印。它不会循环回到值 1...9
等。
另一方面,如果我在打印之前转换为int
:
#include<iostream>
int main()
unsigned char var 0 ;
for(int i = 0; i < 501; ++i)
var += 1;
std::cout << (int)var << '\n';
它确实从1...255
打印,然后从0...255
循环返回。
这是为什么呢?似乎 unsgined char
变量 确实 循环(正如我们从 int 转换中看到的那样)。
使用unsigned char
变量进行数学运算是否安全?我在这里看到的行为是什么?
【问题讨论】:
什么编译器在编译这个,你用什么命令行来运行它? 1..9 的非重复行为可能是由于您使用的 shell 如何处理特定的不可打印字符(而不是 C++ 事物)。 @JohnFilleau 我使用g++ (GCC) 11.1.0
作为g++ test.cpp -o test
。并以./test
的身份运行
你有什么不同吗?例如重复的 1..9?
我看到重复的 1..9,以及 ASCII 集之前和之后的不可打印的替代品。但是 1..9 肯定会重复。
【参考方案1】:
在这种情况下,无符号字符不会被视为数字。这种数据类型实际上是一个字节:
1 byte = 8 bits = 0000 0000 which means 0.
cout 打印的是代表您通过添加 +1 更改的字节的字符。
例如:
0 = 0000 0000
1 = 0000 0001
2 = 0000 0010
.
.
.
9 = 0000 1001
然后,这里开始其他与数字无关的字符。 因此,如果您将其转换为 int,它将为您提供该字节的数字表示,为您提供 0-255 的输出。
希望这可以澄清!
编辑:使解释更清楚。
【讨论】:
“无符号字符不是数字” 它们是。只是cout
对待他们的方式不同寻常。
unsigned char
is an integer
@HolyBlackCat 我的意思是在这种情况下它们不被视为数字,但是是的,我没有正确表达自己。【参考方案2】:
为什么不打印预期的整数值?
问题不在于char
的循环。问题在于 std::ostream
对象和 8 位整数类型的插入操作。这些类型的非成员 operator<<
函数将所有 8 位整数(char
、signed char
和 unsigned char
)视为它们的 ASCII 字符类型。
operator<<(std::basic_ostream)
处理输出 8 位整数类型的规范方法就是您正在做的事情。我个人更喜欢这个:
char foo;
std::cout << +foo;
一元+
运算符将char
类型提升为integer
类型,然后调用整数打印函数。
请注意,整数溢出仅针对unsigned
整数类型定义。如果您使用char
或signed char
重复此操作,则该行为未由标准定义。肯定会发生一些事情,因为我们生活在现实中,但是溢出行为可能因编译器而异。
为什么不重复 0..9 个字符
我使用g++
对此进行了测试,以在 Ubuntu 20.04 上进行编译和 bash。在某些情况下,我的不可打印字符被作为显式符号处理,或者在其他情况下不打印任何内容。非重复行为必须是由于您的外壳如何处理这些不可打印的字符。如果没有更多信息,我们无法回答这个问题。
【讨论】:
以上是关于无符号字符值循环 C++的主要内容,如果未能解决你的问题,请参考以下文章
为啥 ~(true^true) 不正确?布尔运算符(否定)适用于“无符号字符”,但不适用于布尔值? (C++)