整数值在正增量时如何以负值结束?
How does an integer value end up negative when positively incrementing?
我只是写这段代码,但我不知道它是如何工作的。
为什么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 表示的最大值。然后(在你的情况下,正如你的问题所证明的那样 - 它确实没有被标准定义)它滚动到范围的另一端:最大负值。
- 如何反转整数参数包
- enum是C++中的宏变量还是整数变量
- 努力将整数转换为链表。不知道我在这里做错了什么
- 整数不会重复超过随机数
- 在C++中手动调整数组大小
- 检查输入是否不是整数或数字
- C++使用整数的压缩数组初始化对象
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 为什么在这个代码结束循环中没有得到结束
- 通过套接字[TCP]传输数据 如何在C / C ++中打包多个整数并使用send() recv()传输数据
- 如何只允许用户输入正整数
- 如何在c++中从文本文件中逐行读取整数
- C++:如何循环通过向量中的整数元素
- 我可以信任表示整数的浮点或双精度来保持精度吗
- 序列化,没有库的整数,得到奇怪的结果
- 在一定长度后从数组中打印时缺少整数
- 如何读取整数直到线结束
- 步骤程序?开始、结束、步进整数
- 输出一个整数数组以垃圾结束