C允许函数调用自己,这种调用过程称为递归
可以使用循环的地方通常都可以使用递归。有时候循环解决问题比较好,但有时用递归更好,递归方案更简洁,但效率没有循环高。
我们通过一个程序示例来学习什么是递归
该程序中,main()函数调用up_and_down()函数,这次调用成为“第1级递归”。然后up_and_down()函数调用自己,这次调用称为“第2级递归”。接着第2级递归调用第3级递归,以此类推。示例程序中共有4级递归。(为了进一步深入研究递归时发生了什么,程序不仅显示了变量n的值,还显示了储存n的内存地址&n,下篇文章会详细讨论&运算符。)
/*recur.c——递归演示*/
#include <stdio.h>
void up_and_down(int);
int main(void)
{
up_and_down(1);
return 0;
}
void up_and_down(int n)
{
printf("Level %d:n location %p\n",n,&n);//#1
if(n<4)
up_and_down(n+1);
printf("LEVEL %d:n location %p\n",n,&n);//#2
}
输出结果如下:
Level 1 :n location 0x0012ff48
Level 2 :n location 0x0012ff3c
Level 3 :n location 0x0012ff30
Level 4 :n location 0x0012ff24
LEVEL 4 :n location 0x0012ff24
LEVEL 3 :n location 0x0012ff30
LEVEL 2 :n location 0x0012ff3c
LEVEL 1 :n location 0x0012ff48
分析程序:
首先,main()调用了带参数1的up_and_down(),执行结果是up_and_down()中的形式参数n的值是1,所以打印语句#1打印Level 1。然后,因为n<4,up_and_down()(第一级)调用实际参数为n+1(或2)的up_and_down()(第2级)。所以第2级调用中的n的值是2,打印语句#1打印Level 2.以此类推,下面两次调用打印的分别是Level 3和Level 4.
当执行到第4级时,n的值是4,所以if测试条件为假。up_and_down()函数不再调用自己。第4级调用接着执行打印语句#2,也就是打印LEVEL 4,因为n的值为4。此时,第4级调用结束,控制被传回它的主调函数(即第3级调用)。在第3级调用中,执行的最后一条语句是调用if语句中的第4级调用。被调函数(第4级调用)把控制返回在这个位置,因此,第3级调用继续执行后面的代码,打印语句#2打印LEVEl 3。然后第3级调用结束,控制被传回第2级调用,接着打印LEVEl 2,以此类推。
注意:每级递归的变量n都属于本级递归私有。这从程序输出的地址值可以看出(Level 1和LEVEL 1的地址相同,Level 2和LEVEL 2地址相同...)
还可以这样理解,假设有一条函数调用链——fun1()调用fun2()、fun2()调用fun3()、fun3()调用fun4()。当fun4()结束时,控制传回fun3();当fun3()结束时,控制传回fun2(),当fun2()结束时,控制传回fun1()。递归的情况与此类似,只不过fun1()、fun2()、fun3()、fun4()都是相同的函数。
欧克,这就是递归函数的初步认识了,下一篇写原理解析,bye