整数值在正增量时如何以负值结束?

How does an integer value end up negative when positively incrementing?

本文关键字:结束 整数      更新时间:2023-10-16

我只是写这段代码,但我不知道它是如何工作的。

为什么k的值会为负数?如何?

#include<iostream>
using namespace std;
int main()
{
int k=1,j=0;
while(k>j)
{
j=k;
k++;
}
cout<<j<<"n"<<k;
}

它显示整数的范围

int的范围有限。在某些时候,k++会溢出此限制。在此之后,行为是未定义的,任何事情都可能发生。

如果编译器非常保守,那么它只会溢出到负值(特别是在int是 2 补码的几乎无处不在的情况下),但这并不能保证。在这种情况下,while循环将终止。

看看 gcc 在优化和不优化的情况下做了什么。根据标准,这两种行为都是合法的,因为签名溢出行为是未定义的。

使用优化(无限循环):

main:
.L2:
jmp     .L2

没有优化: 指纹:

2147483647
-2147483648

同样,任何事情都可能发生,而不仅仅是上述两种行为。签名溢出未定义。

由于有符号整型的溢出,代码的行为是未定义的

没有明确的方式使k变得消极。正因为如此,一个好的编译器(例如优化 gcc)可以很好地编译while(k > j),有效地while(true)

您的代码将继续递增变量k因为条件k > j为 true。在某些时候,k将等于系统上支持的最大值int值。在下一个循环中执行k++时,结果不能表示为int。这称为整数溢出,根据标准,代码具有未定义的行为。由于它是未定义的行为,我们不能说一般会发生什么 - 它是特定于系统的。

在许多系统上,增加最大值int值的结果将导致最小int值。在这样的系统上,你的代码等效于代码:

#include<iostream>
#include <limits>
int main()
{
int j = std::numeric_limits<int>::max();
int k = j + 1;
std::cout << j << std::endl << k << std::endl;
return 0;
}

在我的系统上,输出是:

2147483647
-2147483648

不要指望这适用于所有系统。在其他系统上,程序可能会崩溃,或进入无限循环或执行任何操作...标准未定义它。

编写代码以使其适用于所有系统的更好方法是:

#include<iostream>
#include <limits>
int main()
{
int j = std::numeric_limits<int>::max();
int k = std::numeric_limits<int>::min();
std::cout << j << std::endl << k << std::endl;
return 0;
}

while 一直持续到 j 被2147483647

2147483647 +1 = -2147483648

整数 32 位溢出并变为负数,停止 while。

在您的代码中,k 在测试时总是比 j 大 1,直到它超过可以用 int 表示的最大值。然后(在你的情况下,正如你的问题所证明的那样 - 它确实没有被标准定义)它滚动到范围的另一端:最大负值。