一、定义
一个函数自己直接或间接的调用自己;
PS:通常,当一个函数的运行期间调用另一个函数时,在运行被调用函数之前,系统需要先完成3件事:
(1)将所有的实在参数、返回地址等信息传递给被调用函数保存;
(2)为被调用函数的局部变量分配存储区;
(3)将控制转移到被调函数的入口;
而从被调用函数返回调用函数前,系统也应完成3件工作:
(1)保存被调函数的计算结果;
(2)释放被调函数的数据区;
(3)依照被调函数保存的返回地址将控制转移到调用函数。
当有多个函数构成嵌套调用时,按照“后调用先返回”的原则,上述函数之间的信息传递和控制必须通过“栈”来实现,即系统将整个程序运行时所需要的数据空间安排在一个栈中,每当调用一个函数时,就为它在栈顶分配一个存储区,每当从一个函数退出时,就释放他的存储区,则当前正运行的函数的数据区必在栈顶。
//函数的互相调用略,,函数自己调用自己具体演示如下(当然,在学C语言的时候,算阶乘和斐波拉契数列时,表示这种函数调用);
# include <stdio.h>
void f(int n)
{
if(n==1)
printf("瓜洲风流倜傥\n");
else
f(n-1);
}
int main(void)
{
f(3);
return 0;
}
二、举例
1、求阶乘
#include <stdio.h>
//假定n>=1
long f(long n)
{
if(1==n)
return 1;
else
return f(n-1)*n;
}
int main(void)
{
printf("%ld\n", f(6));
return 0;
}
2、求1+2+3+·····+100; 略
3、汉诺塔
#include <stdio.h>
void hannuota(int n, char A, char B, char C)//参数A代表要移动的柱子,参数B代表要借助的柱子,参数C代表最后要放的柱子
{
/* 如果是1个盘子
直接将A柱子上的盘子从A移到C
否则
先将A柱子上的N-1个盘子借助C移到B;
再将A柱子上的盘子从A移到C;
最后将B柱子上的N-1个盘子借助A移到C;
*/
if(1==n)
{
printf("将编号为%d的盘子直接从%c柱子移到%c柱子\n", n, A, C);
}
else
{
hannuota(n-1, A, C, B);
printf("将编号为%d的盘子直接从%c柱子移到%c柱子\n", n, A, C);
hannuota(n-1, B, A, C);
}
}
int main(void)
{
char ch1='A';
char ch2='B';
char ch3='C';
int n;
printf("请输入要移动盘子的个数:");
scanf("%d", &n);
hannuota(n, 'A', 'B', 'C');
return 0;
}
4、走迷宫
将地图分成无数个小格子,将每个方向的位置放在栈中,走通就是进栈,后退就是出栈。(具体算法很复杂)
三、递归的应用
树和森林就是用递归的方式定义的;
树和图的很多算法都是以递归实现的;
很多数学公式就是以递归的方式定义的(斐波拉契数列);