无符号字符值循环 C++

Unsigned char value cycle C++

我(认为我)理解不同变量类型的数学运算。例如,如果我超过 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 变量进行数学运算安全吗?我在这里看到的行为是什么?

为什么它不打印预期的整数值?

问题不在于 char 的循环。问题在于 std::ostream 对象和 8 位整数类型的插入操作。这些类型的非成员 operator<< 函数将所有 8 位整数(charsigned charunsigned char)视为它们的 ASCII 字符类型。

operator<<(std::basic_ostream)

处理输出 8 位整数类型的规范方式就是您的操作方式。我个人更喜欢这个:

char foo;
std::cout << +foo;

一元运算符 +char 类型提升为 integer 类型,然后调用整数打印函数。

请注意,整数溢出仅针对 unsigned 整数类型定义。如果您使用 charsigned char 重复此操作,则该行为未被标准定义。肯定会发生一些事情,因为我们生活在现实中,但溢出行为可能因编译器而异。

为什么不重复 0..9 个字符

我使用 g++ 进行编译测试,并在 Ubuntu 20.04 上使用 bash 进行测试。我的不可打印字符在某些情况下被处理为显式符号,或者在其他情况下不打印。非重复行为必须归因于您的 shell 处理这些不可打印字符的方式。如果没有更多信息,我们无法回答这个问题。

在这种情况下,无符号字符不会被视为数字。这种数据类型实际上是一个字节:

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 的输出。

希望这能说明问题!

编辑:使解释更清楚。