我只是写这段代码,但我不知道它是如何工作的。
为什么k
的值为负?怎么样?
#include<iostream>
using namespace std;
int main()
{
int k=1,j=0;
while(k>j)
{
j=k;
k++;
}
cout<<j<<"\n"<<k;
}
显示整数范围
答案 0 :(得分:6)
int
的范围有限。有时k++
会超出此限制。此后,行为是不确定的,任何事情都会发生。
如果编译器非常保守,则它将简单地溢出到负值(尤其是在int
是2的补码的几乎无处不在的情况下),但这不能保证。在这种情况下,while
循环将终止。
查看gcc在进行优化和不进行优化时的作用。根据标准,这两种行为都是合法的,因为未定义签名的溢出行为。
With optimization(无限循环):
main:
.L2:
jmp .L2
Without optimization: 打印:
2147483647
-2147483648
同样,任何事情都可能发生,不仅是以上两种行为。签名溢出未定义。
答案 1 :(得分:3)
由于有符号整数类型的溢出,代码的行为是未定义。
没有k
变为负数的定义方法。因此,一个好的编译器(例如优化gcc)可以将while(k > j)
编译为while(true)
。
答案 2 :(得分:1)
因为条件k
为真,所以您的代码将继续增加变量k > j
。在某个时候,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;
}
答案 3 :(得分:-1)
在您的代码中,测试时k始终比j大1,直到它超过可以由int表示的最大值为止。然后(根据您的问题,就您的情况而言,它确实没有由标准定义)就翻转到范围的另一端:最大负值。
答案 4 :(得分:-1)
这会一直持续到j为2147483647
2147483647 +1 = -2147483648
32位整数溢出并变为负数,从而停止了一段时间。