对递归执行过程的简单理解

1. 分析代码

#include <stdio.h>
 
void fun(int n)
{
    printf("1th - Level: %d  Address: %d
", n, &n);
    if(n < 3)
        fun(n+1);
    printf("2th - Level: %d  Address: %d
", n, &n);
}
 
int main()
{
    fun(1);
    return 0;
}

输出结果为:

2. 分析代码执行过程

  1. 主函数调用fun(1);
  2. 此时n的值为1,随即输出第一行,并得到n的地址****736并将其抽象为aaaa;
  3. 判断,1 < 3,执行递归语句, 重新执行fun函数;
  4. 由于传递参数为n+1,所以本层n的值为2,随即输出第二行,并得到n的新地址****704将其抽象为bbbb;
  5. 判断,2 < 3,执行递归语句, 重新执行fun函数;
  6. 同理可得本层n的值为3,得到第三行结果,并将n的新地址****672抽象为cccc;
  7. 判断,3 < 3不成立,不执行递归, 直接执行第二条输出语句,即输出第四行结果,此时显示n的地址为cccc,容易理解;
  8. 本层结束,返回上一层断点处继续执行,即n为2的那一层,当时程序去已经执行递归,所以接下来执行第二次输出,即得到第五行输出结果,此时n的地址显示为bbbb;
  9. 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. 总结:

  1. 每一级的递归都拥有该函数整套的变量值,此例中变量为n,可以查看变量地址的值来证明。
  2. 如果递归函数的变量过多或递归层数过多,递归过程会占用大量内存来存储中间变量,甚至会导致内存溢出。
  3. 每一次函数调用都会有一次返回,当执行完某一级的递归函数时,它会转移到前一级递归处的下一条语句继续执行,直至完成最高一层递归。(递归我们可以理解为递的过程和归的过程。递的过程,就是从调用到找到调用方法内部终止条件的过程;归的过程,就是从终止条件开始,当执行完最里面的方法时候,返回调用方法的调用方法的过程。)
  4. 位于递归调用语句前的语句执行顺序和各个被调用函数的顺序相同,位于递归调用语句后的语句执行顺序和各个被调用函数的顺序相反(出栈操作)。
  5. 递归函数中必须包含可以终止递归调用的语句,否则无法跳出递归过程。

转自:https://blog.csdn.net/cy_93/article/details/50132449

原文地址:https://www.cnblogs.com/vickylinj/p/14360593.html