我从CS50学习C语言。当我运行我的代码时,它表示“已签名的整数溢出”#。
#include <stdio.h>
#include <cs50.h>
int main(void)
{
int x = 41;
int c = 0;
while(x>=25)
{
c = c+1;
}
printf("%i\n", c);
}
有人可以解释这意味着什么吗?
答案 0 :(得分:1)
您的while条件将始终为true,这意味着循环将永远运行,在每次迭代中向c
添加1。
由于c
是(signed
)int
,这意味着它会缓慢增加到它的最大值,之后下一个增量将是UB(未定义的行为) )。许多机器在这个特定的UB中会做的是将c
变为负数,我猜这不是你想要的。这是由于称为&#34;有符号整数溢出&#34;。
我们假设32位int
并使用两个补码。 signed int
在二进制sign bit (0 for positive, 1 for negative) | 31 bits
中看起来像这样。零看起来像000...00
,类似于000...01
,依此类推。
Max signed int看起来像0111...11
(2,147,483,647)。向此数字添加1时,您将获得100...000
,这会翻转符号位,现在会产生负数。向此添加另一个将导致100...001
再次具有符号位意味着它仍然是负数...
将c
声明为未签名会确保c
仍然是非负面的。此外,使用while(x-- >= 25)
结束循环也可能是一个好主意:)
答案 1 :(得分:0)
嗯......你有一个无限循环,因为你的值x
总是大于25,因为你不减少它。
因为循环是无限的,你的值c
到达int的最大大小(如果是4bytes则为2,147,483,647)。
你可以试试这个以逃避无限循环:
int main(void)
{
int x = 41;
int c = 0;
while (x >= 25)
{
c = c+1;
x--;
}
printf("%i\n", c);
}
答案 2 :(得分:0)
首先,您需要知道“有符号整数溢出条件”是什么。
当数学运算导致数字超出数据类型的范围时,会出现这种情况,在您的情况下,这是有符号整数溢出。
这是因为你的循环无限循环,因为x >= 25
将永远为真。
答案 3 :(得分:0)
&#34;有符号整数溢出&#34;表示您尝试存储的值超出了该类型可以表示的值范围,并且该操作的结果是 undefined (在这种特殊情况下,您的程序会暂停误差)。
由于您的while
循环永不终止(x >= 25
评估为true,而您永远不会更改x
的值),因此您需要向c
添加1才能到达超出签名int
可以表示范围的值。
请记住,在C中,积分和浮点类型具有固定大小,这意味着它们只能表示固定数量的值。例如,假设int
是3位宽,这意味着它只能存储8个不同的值。这些值取决于位模式的解释方式。你可以存储&#34; unsigned&#34; (非负)值[0..7]
,或&#34;签署&#34; (负数和非负数)值[-3...3]
或[-4..3]
取决于表示形式。您可以通过以下几种方法来解释三位的值:
Bits Unsigned Sign-Magnitude 1's Complement 2's Complement
---- -------- ------------- -------------- --------------
000 0 0 0 0
001 1 1 1 1
010 2 2 2 2
011 3 3 3 3
100 4 -0 -3 -4
101 5 -1 -2 -3
110 6 -2 -1 -2
111 7 -3 -0 -1
大多数系统使用2的补码作为有符号整数值。是的,符号幅度和1的补码具有零的正负表示。
所以,让我们说c
是我们的3位签名int
。我们从0
开始,每次循环添加1
。在c
为3
之前,Eveything没问题 - 使用我们的3位有符号表示法,我们无法表示值4
。操作的结果是未定义的行为,这意味着编译器不需要以任何特定方式处理该问题。从逻辑上讲,你期望价值能够回归&#34;根据使用中的表示形式为负值,但即使这样也不一定正确,这取决于编译器如何优化算术运算。
请注意,无符号整数溢出是明确定义的 - 您可以绕过&#34;#34;回到0.
答案 4 :(得分:0)
一个整数在达到最大值之前只能容纳这么多数字。在你的 while 循环中,它说在 x>=25
时执行它。由于 x 是 41 并且 x 的值永远不会减少,这意味着 while 循环将始终执行,因为它从 41>=25
起始终为真。
一个整数最多只能容纳数字 2,147,483,647,这意味着由于 C 将继续添加到自身,因为一旦达到 2,147,483,647,while 循环将始终为真它会给你一个错误,因为一个整数不能超过那个它没有足够的内存。