C语言中的溢出和下溢

时间:2016-07-06 19:15:08

标签: c

您能解释一下溢出和下溢对signed charunsigned 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 ...
为什么呢?

3 个答案:

答案 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。