这题很多人一看觉得很简单,如果你的代码如下,那么恭喜你掉坑了
#include <stdio.h>
int main()
{
int result = 1;
for (int i = 1; i <= 100; i++)
{
result *= i;
}
printf("%d\n", result);
system("pause");
return 0;
}
结果截图:
结果为0!!!这是因为没有考虑溢出,因为100的阶乘是一个很大的数,int类型放不下这么大的数,long int 也放不下
如果你用double类型变量来放结果,则会有很大的误差,计算结果不精确,那么如何解决这个问题呢?这里我想到的使用数组
来存放结果,通过手工模拟乘法的方式,来计算并进位。
#include <stdio.h> #define N 500 int main(void) { int count = 1; //此变量用来统计计算结果的长度,也是fact数组被用了多少个元素 int i, j,carry = 0; //carry保存每次的进位 int fact[N] = { 1}; //将fact[0]初始化为1,方便后面的计算 for ( i = 1; i <= 100; i++) //求100的阶乘,所以i小于等于100 { for (j = 0; j < count1; j++) //i与数组中的每一位相乘,此循环依赖与数组被占用的元素个数 { fact[j] = fact[j] * i + carry; //计算乘积,并且加上来自于低位的进位 carry = fact[j] / 10; //计算进位 fact[j] %= 10; //计算进位后,此位实际的数值 } while (carry > 0) //上一个for循环结束后,最高位任然可能有进位,所以要处理 { fact[count++] = carry; //将来自最高位的进位保存,此时阶乘的结果又增加了一位,所以count要加1 if (fact[count - 1] > 9) //由于最后一次进位可能是一个比较大的数,有可能还要进位 { carry = fact[count - 1] / 10; fact[count - 1] %= 10; } else { carry = 0; //如果不需要进位,将carry置为0,以免影响后面的计算 } } } for (i = count - 1; i >= 0; i--) //上面的计算将结果的高位放在数组的高地址,所以得逆序输出 printf("%d", fact[i]); printf("\n"); system("pause"); } 最终结果如下:
![]()
注:上述的叙述可能不充分,你可能看不懂,自己多想想,然后动手写写,调试调试就应该能写出来我第一次写也写不出来,看了好多人的代码,看的也不是太懂,也没有注释,最后自己想了想然后慢慢的才写出来。