對遞迴的進一步理解

2021-09-23 01:43:04 字數 2346 閱讀 6795

這週看了一道求陣列排列的題目,解法用了遞迴,看懂之後自己對遞迴的理解更深了。

遞迴的定義

遞迴是指程式呼叫自身,但呼叫時必須改變呼叫引數,直到某個引數滿足退出條件。函式呼叫的過程會用到run-time stack,遞迴時棧中的內容有相似性,但是每一層的差異最終會導致執行棧增長的停止,並且從棧頂返回。

理解遞迴,最終還是要歸結到理解函式呼叫過程中執行棧的增長和退出。

run-time stack

函式p呼叫函式q時,棧頂增長,棧頂的位址向低位址方向移動,暫存器%rsp的值減少。當q中的**遇到return子句或者**全部執行之後q返回,棧頂退出,函式p恢復呼叫q之前的狀態,接著執行。

**演示和解釋

#include

void

recursive_ill

(int

*x,int level)

}int

main()

大家可以先自己思考一下最終列印出來的結果是多少。..

....

....

....

...答案就是1110。我們接下來分析一下這個結果是怎麼來的。

這個就是上面那段**的執行時函式呼叫棧的形式,因為recursive_ill(0)會馬上返回,所以沒有畫出來。

首先,main()呼叫recursive_ill(3),在recursive_ill(3)中,i=0,(*x)加一,

然後呼叫recursive_ill(2),在recursive_ill(2),i=0,(*x)加一,

然後呼叫recursive_ill(1),在recursive_ill(1)中,i=0,(*x)加一,

然後呼叫recursive_ill(0),馬上返回;

此時,recursive_ill(1)恢復,recursive_ill(1)中,i=1,(*x)加一,

然後呼叫recursive_ill(0),馬上返回;

。。。。。。

當在recursive_ill(1)中,i=10時,返回,

此時,recursive_ill(2)恢復,recursive_ill(2)中,i=1,(*x)加一,

然後呼叫recursive_ill(1),在recursive_ill(1)中,i=0,(*x)加一,

然後呼叫recursive_ill(0),馬上返回;

。。。。。。

當在recursive_ill(2)中,i=10時,返回,

此時,recursive_ill(3)恢復,在recursive_ill(3)中,i=1,(*x)加一,

然後呼叫recursive_ill(2),在recursive_ill(2),i=0,(*x)加一,

然後呼叫recursive_ill(1),在recursive_ill(1)中,i=0,(*x)加一,

然後呼叫recursive_ill(0),馬上返回;

。。。。。。

當在recursive_ill(3)中,i=10時,返回,

main()呼叫printf,列印出x的值。返回,程式結束執行。

總結我們對上面那個例子的呼叫過程做個總結:

函式p呼叫函式q,當棧頂從函式q回退到函式p時我們說呼叫結束。

在上面的**中,main()呼叫recursive_ill(3),recursive_ill(3)呼叫recursive_ill(2),recursive_ill(2)呼叫recursive_ill(1),recursive_ill(1)呼叫recursive_ill(0)。

main()對recursive_ill(3)的呼叫結束時,(*x)在recursive_ill(3)中進行了10次加一,

每一次加一之後都要呼叫recursive_ill(2),(*x)在recursive_ill(2)中進行了10次加一,

每一次加一之後都要呼叫recursive_ill(1),(*x)在recursive_ill(1)中進行了10次加一,

每一次加一之後都要呼叫recursive_ill(0),(*x)沒有變化。

所以(*x)在recursive_ill(3)中總共進行10次加一,在recursive_ill(2)中總共進行100次加一,在recursive_ill(1)中總共進行1000次加一。

所以,main()呼叫recursive_ill(3)結束後,(*x)總共進行1110次加一,如果開始(*x)是0,最終(*x)的值是1110。

對mock的進一步理解

get judgedoc shinfo time node api.side effect self.side effect judgedoc shinfo 2009 12 11 def side effect judgedoc shinfo self,verify open from 1 time...

bufferedReader進一步理解

public static void main string args string mystring system.out.println 請輸入明文 bufferedreader buf new bufferedreader new inputstreamreader system.in try...

進一步理解委託

前面一篇文章介紹了委託的基本知識,接下來就進一步研究一下委託。其實,剛開始覺得委託型別是乙個比較難理解的概念,怎麼也不覺得下面的 assembleiphonehandler 是乙個型別。public delegate void assembleiphonehandler 按照正常的情況,如果我們要建...