C语言中自定义函数中递归调用是怎样工作的?
这个程序时实现N的阶乘,但始终不明白ff();函数中else…两句的工作原理。请具体解释下面//两句。
long ff(int n)
{
long f;
if(n<0) printf("n<0,input error");
else if(n==0||n==1) f=1; //为什么f=1,就不再继续递归调用?
else f=ff(n-1)*n;//这一步到底是怎么工作的?
return(f);
}
main()
{
int n;
long y;
printf("\ninput a inteager number:\n");
scanf("%d",&n);
y=ff(n);
printf("%d!=%ld",n,y);
getch();
}
先说工作原理:
首先要清楚,递归就是某个函数直接或间接地调用了自身,这种调用方式叫做递归调用。说白了,还是函数调用。既然是函数调用,那么就有一个雷打不动的原则:所有被调用的函数都将创建一个副本,各自为调用者服务,而不受其他函数的影响。
你的ff函数,递归多少次,就有多少个副本,再利用内存的栈式管理,反向退出。这个最好找一下“栈”这方面的东西看看,挺容易的,就像子弹匣一样,先进后出。
你不理解,很有可能是因为误以为该这几行代码被反复使用了。从某种意义上说,这是不对的,因为就像刚才说的,一旦被调用,他将在内存中复制出一份代码,再被调用就再复制一份,换句话说,你可以吧同一个函数的多次调用理解称谓多个不同函数的一次调用,这样也会会简单些。
再说=1和=0是为什么退出。递归,很需要注意的就是死递归,也就是说,某一个函数进入了无限调用自身的情况,永无止境地消耗内存等资源,这在编程方面是一大忌。但凡是递归的函数,一定会在某一个地方存在能够返回上一层函数的代码,否则必定死递归。ff函数中,那个else就是返回的出口,你可以这样想,如果没有那个if来进行判断,你递归到什么时候算完?ff是不是会一直调用自己呢?别指望被调用的函数会自动结束,因为一旦某个函数A中调用了函数B(或者自己),那么A中的代码会停在调用的位置,而转向B中去执行,同理,如果B又调用函数C,那么B又停在调用的位置,去执行C,如果无限调用,那么程序是永远不会结束的。当然,也有这种情况,A调用B,然后继续自己的代码,不管B的死活,这种不在我们的讨论范围内,因为那牵扯到另一种编程方式:多线程。(我们现在说的是单线程)
给你拆极不看看吧:
求3!=?
一层执行到f=ff(3-1)*3;停止,执行二层ff(3-1),也就是ff(2)
二层执行到f=ff(2-1)*2;停止,执行三层ff(2-1),也就是f(1)
三层执行到else if(n==0||n==1) f=1;然后return(f)到二层的ff(2-1)的位置,二层继续执行
二层执行f=1*2; 然后就return(f)到一层ff(3-1)的位置,一层继续执行
一层执行f=2*3; 然后就return(f)到了最初调用ff(3)的main函数里,所以就得到y=6
大体过程就是这样的
这里每次一层都相当于一个不同的函数,你可以给他们起名为ff1,ff2,ff3.....这样就不混了。只要注意一点,调用一次,不是在代码本身上执行,而是会复制出一份在执行,虽然不太恰当,但足以说明问题。