无符号字符值循环 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&lt;&lt; 函数将所有 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。在某些情况下,我的不可打印字符被作为显式符号处理,或者在其他情况下不打印任何内容。非重复行为必须是由于您的外壳如何处理这些不可打印的字符。如果没有更多信息,我们无法回答这个问题。

【讨论】:

以上是关于无符号字符值循环 C++的主要内容,如果未能解决你的问题,请参考以下文章

为啥 ~(true^true) 不正确?布尔运算符(否定)适用于“无符号字符”,但不适用于布尔值? (C++)

C++ 使用 istringstream 将整数读取为无符号字符

C++ 从无符号字符数组创建 GUID

值 247 的无符号字符超出范围?

opencv c++:将图像矩阵从无符号字符转换为浮点数

C# 中的无符号字符使用哪种数据类型?