C++中无符号字符溢出
Overflow of an unsigned char in C++
我在这里找到了以下代码片段https://www.toptal.com/c-plus-plus/interview-questions问题是:这个循环将执行多少次?解释您的答案
unsigned char half_limit = 150;
for (unsigned char i = 0; i < 2 * half_limit; ++i)
{
// do something;
}
答案是无限的。
表达式2*half_limit将被提升为int(基于C++转换规则(,并且将具有值300。然而,由于我是一个无符号字符,它由一个8位值重新读取,在达到255将溢出(因此将返回到0(,并且循环因此将永远持续下去。
我猜了45次(300-255(,因为我记得如果你增加一个无符号整数计数器,当它溢出时,计数器将再次从0开始。好吧,它从一个整数转换为一个无符号字符,为什么不是255呢?
谢谢
为什么不是255?
因为255小于300。在下一次迭代中,i
将为0,也小于300。用8位整数表示的数字都不能达到300。
从技术上讲,正确的答案是迭代次数取决于unsigned char
的大小。在使用16位字节的系统上,不会有任何问题。
答案的另一个问题是,除非在循环中采取某些操作,例如生成一些输出,否则语言中不允许"无限"循环。因此,实际上,示例程序具有未定义的行为(假设为8位字节(。报价来源标准:
[intro.progress]
实现可能假设任何线程最终都会执行一个以下内容之一:
- 终止
- 调用库I/O函数
- 通过易失性glvalue执行访问,或者
- 执行同步操作或原子操作
[注意:这是为了允许编译器转换,例如删除空环路,即使在无法证明终止的情况下也是如此。——终止注]
小于int
的类型上的算术首先将它们提升为int
。因此CCD_ 5就是CCD_。假设unsigned char
所能代表的最大值是255
,则所有的值i
都可能满足i < 2 * half_limit
,因此这是一个无限循环。
2 * half_limit
与相同
int(2) * int(half_limit)
half_limit被提升为一个整数来进行乘法运算,表达式的结果是300。因此,
i < 2 * half_limit
成为
i < int(300)
其中,我被提升为int来进行实际比较,但由于我是一个无符号字符,它永远不会大于255(假设我们的无符号字符是8位(,因此比较有效:
int(smaller than 256) < int(300)
当然,这总是正确的。
#include <iostream>
int main(int argc,char* argv[]){
unsigned char half_limit = 150;
for (unsigned char i = 0; i < 2 * half_limit; ++i)
{
printf("%.2Xn", i);
}
}
用mingw g++编译了这段代码。给了我一个无限循环,打印出了十六进制i的值表明它每次溢出时都会被重置。也许当它溢出时会设置一个标志。。如果错误,请纠正我
- C++字符*缓冲区的大小
- HEX值到wchar_t字符(UTF-8)的转换
- 为什么 Serial.println(<char[]>);返回随机字符?
- 我的字符计数代码计算错误.为什么
- 字符串-C++后显示的随机字符
- C++中无符号字符溢出
- 自定义 std::fstream,std::filebuf 的溢出和下溢函数未为每个字符调用
- 将字符数组转换为结构时出现问题. 结构的字符数组变量溢出
- 如何检查溢出将字符*[]转换为无符号短短
- 读取文件时字符缓冲区溢出
- 将字符数组传递给使用构造函数初始化的类构造函数时防止溢出
- 字符溢出在 ~125+
- 使用 sprintf 分配给字符数组并将字符指针作为输入之一时缓冲区溢出
- 组合 std::string 和 C 字符串会导致缓冲区溢出
- boost::融合解析长字符串会导致堆栈溢出
- 无符号字符模板值溢出
- 读取/写入文件,字节丢失,可能是字符溢出
- C++字符定义来自二进制字符串和溢出
- 溢出字符数组每次都覆盖完全相同的字符串-为什么?
- 为什么在添加两个字符时没有出现整数溢出?