第七章 函数
第三节 函数递归调用精彩演绎
1. 函数递归调用的定义
-调用栈:一块系统分配给这个程序中有特殊用途的内存,存储形式参数,函数调用关系,局部变量…这段内存是有限的,一旦超过这个内存大小,就会出现崩溃
-定义:在函数体内调用自己的函数,执行函数将反复调用自己的函数,每调用一次就进入一个新层
下面的算法会出现死循环,所以自己调用自己的方式,所以必须要定义出口(递归结束条件),使得递归调用能够结束.
#include <iostream>
void Recursive_func() {
printf("we are now in the Recursive_func()\n");
Recursive_func();
}
int main() {
std::cout << "Hello, World!" << std::endl;
Recursive_func();
return 0;
}
2. 递归调用的出口
- 一个范例:求阶乘
#include <iostream>
//计算5的阶乘 1*2*3*4*5
int Factorial_func(int i) {
int result;//保存阶乘结果
if (i == 1) {
return 1;//这里就是递归调用函数的出口
} else {
result = Factorial_func(i - 1) * i;
}
return result;
}
int main() {
std::cout << "Hello, World!" << std::endl;
int res = Factorial_func(5);
printf("Factorial_func result: %d", res);
return 0;
}
3. 必须用递归吗? 递归的优缺点
递归的优点:
- 代码少,代码看起来简洁精妙
递归的缺点:
- 不好理解
- 如果调用的层次太深,调用栈可能会溢出,如果真出现这种情况,说明不能用递归解决该问题
- 效率和性能都不高,深层次的调用,要保存的东西很多,所以效率和性能高不起来
有些问题不用递归也行,有些问题,可能必须用递归解决:汉诺塔
递归函数的直接和间接调用问题
- 递归函数直接调用: 调用函数f的过程,f函数又调用自己
- 递归函数的间接调用: 调用函数f1的过程中,调用函数f2函数,f2函数中又调用了f1的函数