我正在尝试学习一些C编程,并且为了测试我的基本技能,我正在制作一个计算阶乘的简单程序。但是,不是给5的阶乘给出120的正确答案,而是给出-1899959296。怎么了?这是我的代码:
#include <stdio.h>
int factorial(int x)
{
int i;
for(i=1; i < x; i++)
x *= i;
return x;
}
int main()
{
int a = 5, b;
b = factorial(a);
printf("The factorial of %d is %d \n", a, b);
return 0;
}
提前致谢!
答案 0 :(得分:3)
int factorial(int x)
{
int i;
int count =x;
for(i=1; i < count ; i++)
x *= i;
return x;
}
像这样修改。你的问题是循环计数..由于x的值正在改变,循环可能变为无限..
答案 1 :(得分:3)
您的问题是函数factorial()
不断修改x
。对于最初为x
或更多3
的任何x
,fact(3)
将继续增加,因此循环将继续运行。
考虑您是否致电x = 3
。
使用i = 1
调用该函数。使用x
的循环的第一次迭代将1
乘以x
。因此3
仍然具有i
的值。 i
2
将增加到3
,小于x
,因此下一次迭代开始。
循环的第二次迭代将2
乘以6
,得到i
的结果。 3
递增到6
,小于x
,因此下一次迭代开始。
第三次迭代会将3
乘以18
,得到i
的结果。 4
递增到18
,小于i < x
,因此下一次迭代开始。
注意上面的模式.....结束条件是i
。 x
在每次迭代中递增。 i
乘以x
。这意味着i
的增长速度明显快于i < x
....这意味着x
始终为真。
差不多......最终逻辑崩溃了。
最终i
会溢出 - 将其乘以int
的结果将产生超出int
中可存储的结果的结果。溢出3
的结果是未定义的.....在那一点上可能发生任何事情。
将上述说明与要求计算jest.mock()
的阶乘的情况进行比较。你会做类似的步骤吗?可能不是。
答案 2 :(得分:1)
C)您使用x作为for循环i < x
B)你也在每个循环x *= i
上几乎以指数方式增加x,你的循环不起作用。
你可能已经注意到你得到了一个负数。循环退出的原因是你选择输入x作为32位有符号整数(默认为int
) - 处理器以二进制方式工作:所以一旦你比实际可能只有32更高比特,它仍然试图做数学,但它会丢失数据并循环回到负数。因此,一旦x循环并变为负数,则i > x
并且循环退出。
答案 3 :(得分:1)
错误在for
,数字的阶乘是 n * n-1 * ... * n-(n-1),所以为了解决这个问题,只需在x - 1中开始索引并递减直到它变为1,抱歉我的英语不好,我希望你能理解我说的话。
这是答案:
for ( i = x - 1; i > 1; --i )
x *= i;
只是为了解释为什么是负数,首先我们必须了解for
所宣告的内容。
for(i=1; i < x; i++)
x *= i;
我们可以看到它在循环中继续的条件为i < x
,但在其中x
的值为x * i
(x * = i or x = x * i
),因此x
没有常数值并且总是在增加,i
以小于x
的速度增加,因为i
总是添加到1({{1} }}),导致i ++, i + = 1 or i = i + 1
无法访问,然后x
将处于无限循环中。
但是每个类型都有它的范围,而for
是4个字节,因此是32位,会发生的事情是int
超过这个范围时有着名的整数溢出,这就是为什么其值为负,则x
的条件变为false,然后for
停止。
我们必须记住,数字在二进制形式的内存中表示,最后一个二进制数表示数字是正数还是负数,0表示正数,1表示负数,当整数溢出发生时,最后一个数字发生变化到1,使它如此消极。
为了更好地理解这一点,有些链接可以提供帮助: