這週看了一道求陣列排列的題目,解法用了遞迴,看懂之後自己對遞迴的理解更深了。遞迴的定義
遞迴是指程式呼叫自身,但呼叫時必須改變呼叫引數,直到某個引數滿足退出條件。函式呼叫的過程會用到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 按照正常的情況,如果我們要建...