2017-08-12 112 views
9
void main() { 
    int i; 
    if (i < 0) { i = -i; }; 
} 

任何人都可以帮助我理解为什么在上面的程序中可能发生溢出吗?为什么在下面的程序中会发生溢出?

+4

未定义的行为。该变量未被初始化。并且否定最负的可能整数在二进制补码运算中产生相同的值 –

+1

在2的补码中, INT_MIN | > INT_MAX – BLUEPIXY

+1

当'i == INT_MIN'以2的补码表示时。 –

回答

13

可能会发生溢出,因为二进制补码中整数表示的范围不对称:可以表示的最小负数的幅度是可以表示的最大正数的幅度加1。例如,在32位系统上,值为-2,147,483,6482,147,483,647。这就是为什么否定-2,147,483,648会导致溢出的原因:否定的结果为正值2,147,483,648,不能用相同大小的int表示。

请注意此问题的逆是不正确的:否定一个正数不会导致溢出:

if (i > 0) { i = -i; } // No overflow here 
+2

@Tom请注意,MSVC在'limits.h'中有'#define INT_MIN(-2147483647 - 1)'。 –

+0

明白...非常感谢 – Tom

1

的原因整数溢出是在运算试图创建一个数值即在可以用给定位数表示的范围之外,或者大于最大值或者小于最小可表示值。

  • 那么,在你的情况下,变量i未初始化。所以在这里会发生什么是分配给变量i整数类型的内存空间将包含一些垃圾值。
  • 如果内存地址包含最大可能的整数值-2^31(-2,147,483,648),那么否定此值将导致整数溢出。

我希望这有助于。

1

当main启动时,您的堆栈中的“i”值是未定义的。调用main()之前运行的启动代码可以在那里留下任何东西。

Addig对Kashif说什么,负整数可以比非负整数低一个数值,因为负数不需要留下零空间。当符号反转时,符号位中的“1”(所有剩余位为零)会导致溢出。

在16位:-0x8000 ==〜为0x8000 + 1 == 0x7FFF的+ 1 ==为0x8000
// “ - ” 负值==反相+ 1 ==反转+ 1 ==最终是相同的

该值的可能性很低,但存在。它不会发生,除非堆栈恰好包含违规号码。

相关问题