20201023_081.遞迴函式_函式呼叫記憶體分析_棧幀的建立

Minsky Yi發表於2020-10-23

遞迴函式

遞迴函式指的是:自己呼叫自己的函式,在函式體內部直接或間接地自己呼叫自己。遞迴類似於大家中學數學學習過的“數學歸納法”。 每個遞迴函式必須包含兩個部分:

  1. 終止條件
    表示遞迴什麼時候結束。一般用於返回值,不再呼叫自己。
  2. 遞迴邏輯關係
    把第 n 步的值和第 n-1 步相關聯。

注意:遞迴函式會在棧中建立大量的函式物件,過量的消耗記憶體和運算能力,在處理大量資料時慎用。

【案例】

def test(n):
    print('test{}begin'.format(n))
    if n == 1:
        print(1)
    else:
        test(n - 1)
    print('test{}finished'.format(n))
    
    
test(3)

執行結果:
[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片儲存下來直接上傳(img-vrk1tkyO-1603465725617)(en-resource://database/7411:0)]@w=120
棧記憶體過程分析:
最開始執行test(3),在test(3)函式裡一行一行執行,過程中列印了結果的第1行:“test3begin”,判斷完n不=1,–>else: ,馬上要執行下一條程式碼,棧裡是這樣的
在這裡插入圖片描述
所以執行test(2),這時test(3)還沒執行完。在tes(2)函式裡一行一行執行,過程中列印了結果的第2行:“test2begin”,判斷完n不=1,–>else: ,馬上要執行下一條程式碼,棧裡是這樣的
在這裡插入圖片描述
同理,執行test(1),這時test(3)、test(2)還沒執行完。棧裡是這樣
在這裡插入圖片描述
然後就在test(1)函式裡一行一行執行,
–>列印結果的第3行:“test1begin”,
–>判斷n=1,列印結果的第4行:“1”,else的不執行了
–>列印結果的第5行:“test1finished”
然後test(1)就執行完了,test(1)佔用的棧空間釋放掉,棧裡變成了這樣
在這裡插入圖片描述
然後繼續執行test(2)中剩下的程式碼,列印結果的第6行:“test2finished”,列印完後,test(2)執行完,test(2)佔用的棧空間釋放,棧裡變成了這樣
在這裡插入圖片描述
同理,接下來繼續執行test(3)中剩下的程式碼,列印結果的最後一行,第7行:“test1finished”,列印完,test(3)也會執行完,釋放棧空間。接下來還會釋放掉定義test函式的棧空間(上面的圖沒畫),整個程式執行完成。

相關文章