为什么下面给出的程序打印-128
#include <stdio.h>
main()
{
char i = 0;
for (; i >= 0; i++)
;
printf("%d",i);
}
我也可以在没有类型转换的情况下将int值赋给char。如果我在for循环中使用了print语句,则打印到127这是正确的,但是这个程序当前打印-128。为什么
答案 0 :(得分:5)
如果平台上char
是signed
类型,则程序的行为未定义:溢出signed
类型是C中的未定义行为。
值为-128的2的补码8位数与具有值+128的无符号8位数具有相同的位模式。看来这就是你的情况。当然,-128是循环的终止条件。 (你甚至可以把它称为“最小的负面”)。但不依赖于此。
答案 1 :(得分:2)
根据N1570,char
是否已签署是实施定义的:(强调我的)
6.2.5类型
15 char,signed char和unsigned char这三种类型统称为字符类型。 实施应 将char定义为具有相同的范围,表示和行为 签名字符或未签名字符。
如果它是无符号的,它永远不会溢出:
9有符号整数类型的非负值范围是a 对应的无符号整数类型的子范围,和 每种类型中相同值的表示是相同的。 :一种 涉及无符号操作数的计算永远不会溢出,因为a 结果无法由结果无符号整数表示 type是以大于最大值的数量减少的模数 可以由结果类型表示的值。
例如,假设UCHAR_MAX == 127
(通常它会是255,127 + 1 = (127 + 1) % (UCHAR_MAX + 1) = (127 + 1) % (127 + 1) = 0
。
但如果它已签名,则行为未定义,这意味着任何事情都可能发生。 CHAR_MAX + 1可以等于CHAR_MIN,0或其他。更重要的是,“未定义的行为”表示程序可能崩溃,尽管实际上不太可能。
在您的情况下,似乎char
已签名,CHAR_MAX + 1 == CHAR_MIN
。为什么?只是因为你的实现定义了这一点,而且你很幸运能够错过这次崩溃。但这根本不可携带和可靠。