您能解释一下溢出和下溢对signed char
和unsigned char
的影响吗?
int main () {
signed char c;
scanf("%d",&c);
printf("%d\n",c);
printf("%c\n",c);
return 0;
}
在这种情况下,如果感谢scanf
,我会将c=200
置于溢出状态,并由第一个printf
显示。
第二个printf
给出了相同的ASCII符号200 ...
为什么呢?
答案 0 :(得分:6)
scanf
' %d
期待int
,所以给它任何其他内容都是未定义的行为。
你应该这样做:
int d;
scanf("%d", &d);
whatevertype c = (whatevertype)d;
但是,未定义有符号整数溢出。但是如果你使用无符号类型,比如
unsigned char c = (unsigned char)d;
然后c
保证d
模数为unsigned char
中位数的幂。
答案 1 :(得分:0)
每个编译器都在特定硬件上的特定计算机上运行。
例如,假设我们的机器/处理器有符号整数在16位范围内。这意味着MAX_INT将为0x7fff十六进制值,即32767十进制值,MIN_INT将为0x8000十六进制值,即-32768十进制值。
大多数机器都有ALU控制寄存器,用于定义有符号整数在溢出时的行为方式。该寄存器通常具有饱和标志。
溢出示例: 如果设置饱和标志,则与上次有符号整数ALU操作的结果大于MAX_INT的情况相比,结果将设置为MAX_INT。 例如,如果最后一个操作是将0x7ffe添加到0x2,那么结果将是0x7fff。
如果未设置饱和标志,则与上次有符号整数ALU操作的结果大于MAX_INT的情况相比,结果可能会设置为正确结果的低16位。在我们的例子中,0x7ffe + 0x2 = 0x8000,这是最小整数。
在无符号整数的情况下,编译器保证结果将根据C中unsigned int addition的定义。
下溢示例: 每台机器都有MIN_FLOAT定义。并且如果设置饱和标志而不是小于MIN_FLOAT的结果将被舍入到MIN_FLOAT。另外,结果将根据处理器的操作。 (如果您有兴趣了解浮点表示和操作,请在互联网上搜索以了解尾数和指数的术语)。
答案 2 :(得分:0)
您在第一个printf语句中获得溢出的原因是因为您已将char定义为signed char,如果以%d格式打印它们是整数您将从 0-127 和 -1到-128 因为我们都知道char在内存中消耗一个字节并将它们指定为有符号字符,所以你将它们分为正数和负数简单字中的值无符号字节的范围是 0到255 ,因此有符号字符将给出正值和负值范围0-127和-1到-128。