對遞歸執行過程的簡單理解


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. 分析代碼執行過程

  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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM