为什么这段用递归计算阶乘只能跑到34

玩笑 2011-05-28 10:01:52
先说明,不是为了讨论怎么计算阶乘,请各位不在把这变成阶乘讨论,,,写这段代码是为了借助阶乘练习递归和链表操作,
现在的问题是,它只能跑到34,35的时候就报段错误,系统是64位的ARCH,,我是想知道,是不是代码哪里有问题造成的它只跑到34,,
在XP下用CODEBLOCKS带的GCC编译,也是跑到34,会不会是编译器的问题呢?,,
代码绝对可以正确编译运行,是执行时的错误,,,除非是与我的问题有关的,不然,语法错误就不要说了,如果编译不过去,是你编译器的问题,不是我的代码,
希望大家能帮忙指出问题所在,如果是递归在某些情况下受到限制,那以后就不敢随便用递归了
如果编译器不支持C99,把main函数中的循环变量的定义放到循环外面就可以了,我只是写习惯了而已
#include <stdio.h>

#include <stdlib.h>



typedef struct node {

int n;

struct node * next;

} NODE;



NODE * jc(int);

void print(NODE *);



int main()

{

for(int n = 1; n < 36; n++){

print(jc(n));

printf("\t%d\n",n);

}

return 0;

}



void print(NODE * head) {

if(head) {

print(head->next);

printf("%1d", head->n);

free(head);

}

}



NODE * newnode(int n) {

NODE * head;

head = (NODE *)malloc(sizeof(NODE));

head->n = n;

head->next = NULL;

return head;

}



void jw(NODE * head, long n) {

if(n>0) {

if(n>=10 && head->next == NULL) head->next = newnode(0);

int x = head->n + n%10;

head->n = x%10;

jw(head->next, x/10);

jw(head->next, n/10);

}

}



NODE * lj(NODE * head, int n) {

if(head) {

lj(head->next, n);

long x = head->n * n;

head->n = 0;

jw(head, x);

}

return head;

}



NODE * jc(int n) {

return n==1 ? newnode(1) : lj(jc(n-1), n);

}

...全文
193 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
玩笑 2011-05-29
  • 打赏
  • 举报
回复
贴出程序运行结果,为什么34后会中止,是否是编译器或者系统的问题,原因很简单,个人挺喜欢用递归的,因为写起来容易,但如果真的是编译器或者系统什么的限制,那我就应该好好考虑一下是不是不要随便用递归了,,我真希望是自己代码上的问题
[arch@myhost ~]$ ./jc
1 1
2 2
6 3
24 4
120 5
720 6
5040 7
40320 8
362880 9
3628800 10
39916800 11
479001600 12
6227020800 13
87178291200 14
1307674368000 15
20922789888000 16
355687428096000 17
6402373705728000 18
121645100408832000 19
2432902008176640000 20
51090942171709440000 21
1124000727777607680000 22
25852016738884976640000 23
620448401733239439360000 24
15511210043330985984000000 25
403291461126605635584000000 26
10888869450418352160768000000 27
304888344611713860501504000000 28
8841761993739701954543616000000 29
265252859812191058636308480000000 30
8222838654177922817725562880000000 31
263130836933693530167218012160000000 32
8683317618811886495518194401280000000 33
295232799039604140847618609643520000000 34
段错误
[arch@myhost ~]$
玩笑 2011-05-29
  • 打赏
  • 举报
回复
#include <stdio.h>

#include <stdlib.h>

//定义一个结构体,一位十进制数和指向上一位数的结点的指针(表头是结果的最后一位)

typedef struct node {

int n;

struct node * next;

} NODE;



NODE * jc(int);

void print(NODE *);



int main()

{

for(int n = 1; n < 36; n++){

print(jc(n));

printf("\t%d\n",n);

}

return 0;

}

//输出结果,因为接收到的指针是表头,也就是结果的最后一位,所以先打印前面所有的位,然后打印当前位,当到达表尾时(head=NULL),递归开始返回,这样正好就从表尾一项一项往前打印了

void print(NODE * head) {

if(head) {

print(head->next);

printf("%1d", head->n);

free(head);

}

}

//这个函数就是申请一个可以存储新结点信息的内存空间,参数是给新结点赋值的,有点多余,写的时候欠考虑,用上了参数,感觉并不应该影响正常运行,就没改,发动它,其它部分也要发动,

NODE * newnode(int n) {

NODE * head;

head = (NODE *)malloc(sizeof(NODE));

head->n = n;

head->next = NULL;

return head;

}

//这个函数是用来做进位的,因为每个节点只存储一位,所以就要考虑到进位问题

//如,表中存储个2 3 4 5 的列表,当一个乘积是999时,就要考虑怎么把这个999加到这个列表中,列表中的数打印出来是5432,,加上个999应该是6431,过程是这样的

//取最后一个9,5432+9,,然后取倒数第二位9,,前面的数变成 5441, 最后一位不支,变成544+9,,,然后再取倒数第三位9, 结果553中的3也不动了,变成55+9,,最后结果就是1,3,4,6(最终打印是从后向前的)

void jw(NODE * head, long n) {

if(n>0) {

if(n>=10 && head->next == NULL) head->next = newnode(0);

int x = head->n + n%10;

head->n = x%10;

jw(head->next, x/10);

jw(head->next, n/10);

}

}

//这个函数就是用当前列表中的值去"乘"n,只要N先与高位乘,就不用另外的空间存中间结果,一部一部向最低位乘,然后处理进位就行了,

NODE * lj(NODE * head, int n) {

if(head) {

lj(head->next, n);

long x = head->n * n;

head->n = 0;

jw(head, x);

}

return head;

}

//这个是阶乘函数,应该很容易理解了,如果n是1,就返回一个存放着1值的结点(1的阶乘1),那就返回n-1的阶乘,再乘上N的结果

NODE * jc(int n) {

return n==1 ? newnode(1) : lj(jc(n-1), n);

}

玩笑 2011-05-29
  • 打赏
  • 举报
回复
找到原因了,原来是99+1时,处理第二个进位时没申请空间,晕
void jw(NODE * head, long n) {

if(n>0) {

int x = head->n + n%10;

head->n = x%10;

if((x>=10 || n>=10) && head->next == NULL) head->next = newnode(0);

jw(head->next, x/10);

jw(head->next, n/10);

}

}
downmooner 2011-05-29
  • 打赏
  • 举报
回复
哦,我看错了。
那应该是你内存管理出错了。你的递归不可能超过编译器默认的栈大小吧。
ljhhh0123 2011-05-28
  • 打赏
  • 举报
回复
看了半个小时也没看懂你在做什么,只知道在某次的调用后传入jw函数的第一个参数为空指针。
嵌套太多了。
玩笑 2011-05-28
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 downmooner 的回复:]

首先 34的阶乘大概是多少,我估计128位的都会溢出。
还有你的64位,编译器设置了吗?
64位程序 int还是4字节。
[/Quote]
上面代码运行出来的34的阶乘是295232799039604140847618609643520000000,是否正确不清楚,没验证过
我这里是用链表解决的,链表的每一项只存储一个十进制位,,要说是数值大了溢出,也应该是出现负数之类的吧,而不应该是段错误吧,,
downmooner 2011-05-28
  • 打赏
  • 举报
回复
首先 34的阶乘大概是多少,我估计128位的都会溢出。
还有你的64位,编译器设置了吗?
64位程序 int还是4字节。

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧