对递归执行过程的简单理解
1. 分析代码
#include <stdio.h> void fun(int n) { printf("1th - Level: %d Address: %d\n", n, &n); if(n < 3) fun(n+1); printf("2th - Level: %d Address: %d\n", n, &n); } int main() { fun(1); return 0; }
输出结果为:
2. 分析代码执行过程
- 主函数调用fun(1);
- 此时n的值为1,随即输出第一行,并得到n的地址****736并将其抽象为aaaa;
- 判断,1 < 3,执行递归语句, 重新执行fun函数;
- 由于传递参数为n+1,所以本层n的值为2,随即输出第二行,并得到n的新地址****704将其抽象为bbbb;
- 判断,2 < 3,执行递归语句, 重新执行fun函数;
- 同理可得本层n的值为3,得到第三行结果,并将n的新地址****672抽象为cccc;
- 判断,3 < 3不成立,不执行递归, 直接执行第二条输出语句,即输出第四行结果,此时显示n的地址为cccc,容易理解;
- 本层结束,返回上一层断点处继续执行,即n为2的那一层,当时程序去已经执行递归,所以接下来执行第二次输出,即得到第五行输出结果,此时n的地址显示为bbbb;
- n为2时的一层执行结束,返回上一层,即n为1,当时程序去已经执行递归,所以接下来执行输出语句,即得到第六行输出结果,此时n的地址显示为aaaa;
程序结束。
3.例子
function reverse(n) { let y = n % 10; let s = String(y); if (n / 10 >= 1) { s += reverse((n - y) / 10); } return s; }
功能:输入 int 型,返回整数逆序后的字符串。如:输入整型 1234,返回字符串“4321”。
4. 总结:
- 每一级的递归都拥有该函数整套的变量值,此例中变量为n,可以查看变量地址的值来证明。
- 如果递归函数的变量过多或递归层数过多,递归过程会占用大量内存来存储中间变量,甚至会导致内存溢出。
- 每一次函数调用都会有一次返回,当执行完某一级的递归函数时,它会转移到前一级递归处的下一条语句继续执行,直至完成最高一层递归。(递归我们可以理解为递的过程和归的过程。递的过程,就是从调用到找到调用方法内部终止条件的过程;归的过程,就是从终止条件开始,当执行完最里面的方法时候,返回调用方法的调用方法的过程。)
- 位于递归调用语句前的语句执行顺序和各个被调用函数的顺序相同,位于递归调用语句后的语句执行顺序和各个被调用函数的顺序相反(出栈操作)。
- 递归函数中必须包含可以终止递归调用的语句,否则无法跳出递归过程。
转自:https://blog.csdn.net/cy_93/article/details/50132449