美好的一天,同事们!
我需要获取从0到255的连续数字的循环序列。使用无符号字符溢出是否合法:
unsigned char test_char = 0;
while (true) {
std::cout << test_char++ << " ";
}
或者更安全地使用此代码:
int test_int = 0;
while (true) {
std::cout << test_int++ % 256 << " ";
}
当然,在实际代码中会有合理的条件而不是while(true)。
答案 0 :(得分:8)
3.9.1 / 4“无符号整数,声明无符号整数,应遵守算术模2n的定律,其中n是整数特定大小的值表示中的位数”
“这意味着无符号算术不会溢出,因为无法通过结果无符号整数类型表示的结果以比模式生成的无符号整数类型”< / p>
所以,是的,这是合法的。第二种形式是首选,因为它更具可读性。
答案 1 :(得分:2)
即使sizeof(char)始终为1,char也不一定是8位。 (我猜测unsigned char会类似)。
所以在这两者中,如果给出选择,我会更喜欢后者,因为前者甚至可能都不正确。
顺便说一下,对于后者,您可能打算使用unsigned int而不是int?带负数的模数可能会变得棘手(在int溢出之后,正如吉米指出的那样)。如果我正确地回忆起来,我相信它依赖于编译器。
答案 2 :(得分:1)
unsigned char与所有其他无符号整数类型一样,遵循模2 n 算法,因此基本上两种方法都是等价的。使用第一个
答案 3 :(得分:1)
Erik引用的每3.9.1 / 4没有无符号溢出。但是,正如Moron所说,unsigned char
数字系统的模数可能大于256。
请注意,您的表达式不会将% 256
的结果存储回test_int
。安全的方法是
test_int = ( test_int + 1 ) % 256;
std::cout << test_int << " ";
答案 4 :(得分:0)
2个样本的输出完全不同。 第一个将打印字符(a b c d e f g h ......) 第二个将打印整数(0 1 2 3 4 ... 255 0 ......) 无论如何,它取决于你是否有一个overflowexception控件(.NET),否则在旧的C ++中它的值总是有效的,从0到255