一、递归
1.递归
有些非常复杂的问题,可以用递归轻松实现。
- 汉诺塔
- 谢尔宾斯基三角形
- 目录树的索引
函数调用自身就是递归。递归必须要有结束条件,否则程序将崩溃!因此,实现递归要满足两个基本条件:
- 调用函数本身
- 设置了正确的结束条件
举个栗子:递归求阶乘
#include <stdio.h>
long fact(int num);
long fact(int num)
{
long result;
if (num > 0)
{
result = num * fact(num-1);
}
else
{
result = 1;
}
return result;
}
int main(void)
{
int num;
printf("请输入一个正整数:");
scanf("%d",&num);
printf("%d的阶乘是:%d\n",num,fact(num));
return 0;
}
[liujie@localhost sle34]$ gcc test.c && ./a.out
请输入一个正整数:5
5的阶乘是:120
num = 0
时触发结束条件,
递归并没有在执行效率上有任何优势,相反,使用递归更加难以阅读与维护。
2.课后作业
-
请至少列举使用递归的三个缺点?
答:递归的执行效率通常比迭代低很多,所以递归程序要更消耗时间;由于递归函数是不断调用函数本身,在最底层的函数开始返回之前,程序都是一致在消耗栈空间的,所以递归程序要“吃”更多的内存空间;递归的结束条件设置非常重要,因为一旦设置错误,就容易导致程序万劫不复(崩溃)。 -
如果不上机,你能看出下面代码会输出什么吗?
#include <stdio.h> void up_and_down(int n); void up_and_down(int n) { printf("%d ", n); if (n > 0) { up_and_down(--n); } printf("%d ", n); } int main(void) { int n; printf("请输入一个整数:"); scanf("%d", &n); up_and_down(n); putchar('\n'); return 0; }
-
编写一个程序,反向打印用户输入的英文句子。
#include <stdio.h> void getInput(); void getInput() { int ch; if ((ch = getchar()) != '!') { getInput(); } else { printf("反向输出:"); } putchar(ch); } int main(void) { printf("请输入一句以感叹号结尾的英文句子:");