我正在按照以下函数来计算大数link的阶乘,我想了解更多为什么会发生一些事情......
#include<stdio.h>
#define MAX 10000
void factorialof(int);
void multiply(int);
int length = 0;
int fact[MAX];
int main(){
int num;
int i;
printf("Enter any integer number : ");
scanf("%d",&num);
fact[0]=1;
factorialof(num);
printf("Factorial is : ");
for(i=length;i>=0;i--){
printf("%d",fact[i]);
}
return 0;
}
void factorialof(int num){
int i;
for(i=2;i<=num;i++){
multiply(i);
}
}
void multiply(int num){
long i,r=0;
int arr[MAX];
for(i=0;i<=length;i++){
arr[i]=fact[i];
}
for(i=0;i<=length;i++){
fact[i] = (arr[i]*num + r)%10;
r = (arr[i]*num + r)/10;
//printf("%d ",r);
}
if(r!=0){
while(r!=0){
fact[i]=r%10;
r= r/10;
i++;
}
}
length = i-1;
}
我的问题是:
谢谢!
答案 0 :(得分:0)
fact
和arr
中元素的数量;试图访问索引&gt; = MAX的元素会很糟糕。答案 1 :(得分:0)
正如Scott Hunter指出的那样,MAX
是fact
和arr
数组中元素的最大数量,这意味着它是之前结果中可能出现的最大位数程序空间不足。
请注意,代码仅在其数组声明中使用MAX
。它没有使用MAX
来确定它是否试图在这些数组的末尾之外读取或写入内存。这是Bad Thing™。您的“中止陷阱:6”错误几乎肯定会发生,因为尝试计算3251!正是这样做:使用arr
和fact
的过大索引。
要查看给定阶乘所需的位数,您可以增加MAX
(例如,增加到20,000),并使用以下内容替换printf
中现有的main
次呼叫:
printf("Factorial requires %d digits.\n", length + 1);
请注意,我使用length + 1
因为length
本身不是数字位数:而是fact
中包含最高位数的数组位置的索引结果。如果我尝试计算3251 !,输出为:
Factorial requires 10008 digits.
这比fact
中的可用内容多八位,默认MAX
值为10,000。一旦程序逻辑超出了数组中分配的空间,其行为就不确定了。您碰巧看到错误“中止陷阱:6。”
有趣的是,这是我尝试计算3250时的输出!:
Factorial requires 10005 digits.
当MAX
设置为10,000时,程序仍然可以表现得太可靠,因此程序计算3250的事实!成功可能会令人惊讶,但这是未定义行为的本质:也许你的程序会产生正确的结果,也许它会崩溃,也许它会变得自我意识并发射导弹对抗俄罗斯的目标(because it knows that the Russian counterattack will eliminate its enemies over here) 。像这样的编码不是一个好主意。如果您的程序需要比可用空间更多的空间来完成计算,它应该停止并显示相应的错误消息,而不是尝试继续它正在做的事情。