在没有无符号字符的情况下用C显示ASCII字符 无符号字符a; 对于Visual Studio上的(a=32;a

在没有无符号字符的情况下用C显示ASCII字符 无符号字符a; 对于Visual Studio上的(a=32;a,c,visual-studio-2013,infinite-loop,C,Visual Studio 2013,Infinite Loop,),类型char与signed char相同,范围为-128到+127(均包括在内),因此signed char的所有值都低于128。因此,始终满足循环条件a

),类型
char
signed char
相同,范围为-128到+127(均包括在内),因此
signed char
的所有值都低于128。因此,始终满足循环条件
a<128
,循环从不停止


当您有
无符号字符
时,
a
的值在某个点达到128,并且不会有下一次迭代。在这种情况下,如果您尝试将
有符号字符
变量的值增加127(期望值为128),则结果是未定义的。在大多数平台(包括Visual Studio)上,它将自动结束(溢出,因为127是可能的最高值)到可能的最低值-128。

char
意味着它是有符号的或无符号的取决于实现。这使得代码的行为实现定义
在您的计算机上,它似乎是
签名的
签名字符
的最小值和最大值根据C标准分别是
-127
&
+127
。任何大于
127
或小于
-127
的值都不能分配给
a
,否则它将调用未定义的行为


a
达到
127
后,它将递增1,值变为
128
,该值不能由
有符号字符
变量保存,因此代码调用未定义的行为。

是否有符号字符取决于实现,并且可能由编译器和目标archite更改cture

对于大多数(可能是所有现代)CPU体系结构,
有符号字符的范围为-128…127,
无符号字符的范围为0…255(请参见
限制。h
,最小范围为-127…127,无上限)

因此,
char
似乎对您的示例进行了签名。在这里使用
int
进行比较(类型强制-隐式转换),循环的条件将始终为true,因此循环永远不会终止

使用扩展范围的未签名好处,使循环正常运行


请注意,如果在
char
上执行算术,请始终显式使用
signed
unsigned
。后者通常是更好的选择。如果启用警告,编译器可能会帮助您完成此操作。但是,不要依赖于此(而是遵循显示的警告).

为什么当
a
是127时它会停止?答案是错误的。如果
有符号字符
有符号的
溢出调用UB,则没有环绕。@haccks:在大多数平台上它会环绕,尽管从技术上讲你是对的,你不能依赖它。而且,范围不必是
-128
127
.Whoo,如果我们开始考虑C中未正确定义的所有内容,这将是一个冗长且重点不明确的答案。但是,是的,我也尝试在C中解决这个问题。顺便说一句,问题被标记为“Visual Studio”,并且这些内容是按照我解释的方式定义的(包括溢出和范围)@haccks:Wrap-around是UB的一种可能结果。因此你不能说它是“错误的”。它也恰好是大多数编译器的结果。规范甚至(稍微)更窄:
有符号字符的范围定义为
-127..127
。它之外的任何值都是“实现定义的”。(也就是说,我一生都在愉快地使用
-128
)@haccks:C标准不要求带符号字符的范围为-127到127。这只是编译器需要支持的最小范围。大多数编译器使用-128到127。是的,如上所述。我会调用使用
-128
实现定义,而不是未定义的行为,因为它肯定不是用于Visu的UBal Studio。@Jongware:一个实现允许有一个更大的范围,标准只定义了一个最小范围。这就是
限制.h
的目的。
char
可以有24位,例如。@haccks:但这个句子的意思仍然是一样的。你说的是一个最小值(确切地说是“最多”)-127.编译器完全可以保证更大范围的值。
unsigned char a;

for(a=32;a<128;a=a+1)
printf("%d='%c'\t",a,a);
return(0);