无符号字符值循环 C++

Phy*_*PDF 1 c++ types casting char

我(认为我)理解不同变量类型的数学是如何工作的。例如,如果我超过了一个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';
    }
}
Run Code Online (Sandbox Code Playgroud)

这只是输出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';
    }
}
Run Code Online (Sandbox Code Playgroud)

它确实从 打印1...255,然后从0...255.

这是为什么?似乎unsgined char变量确实循环了(正如我们从 int 转换中看到的那样)。

使用unsigned char变量进行数学运算是否安全?我在这里看到的行为是什么?

Joh*_*eau 6

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

问题不在于char. 问题在于std::ostream对象和 8 位整数类型的插入操作。非会员operator<<为这些类型的函数把所有8位整数(charsigned char,和unsigned char)作为ASCII字符类型。

运算符<<(std::basic_ostream)

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

char foo;
std::cout << +foo;
Run Code Online (Sandbox Code Playgroud)

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

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

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

g++在 Ubuntu 20.04 上使用编译和 bash对此进行了测试。在某些情况下,我的不可打印字符作为显式符号处理,或者在其他情况下不打印。非重复行为一定是由于您的 shell 如何处理这些不可打印的字符。如果没有更多信息,我们无法回答。