C|從一個簡單實例看遞歸與循環的對應關係

以下是一個連加的簡單實例,分別用遞歸和循環來實現:

<code>#include <stdio.h>int recur(int n){if(n==1)return 1;return n+recur(n-1);}int loop(int n){int sum=0;while(n>0)sum+=n--;return sum;}int main(){printf("%d\\n",recur(10));// 55printf("%d\\n",loop(10));// 55    getchar();return 0;}/<stdio.h>/<code>

遞歸是如何對應循環的?

遞歸函數參數往遞歸終止條件的方向變化,變化表達式為n-1,終止條件為n==1。由此,該函數會被調用9次,函數參數、返回地址等數據會被保存在棧,函數代碼會被保存在代碼區,相當於代碼會被重複9次,函數返回值會被保存在寄存器中,返回時傳遞給返回函數。

在循環中,同樣對應一個條件表達式以及循環變量的變化,在底層,條件表達式對應一個減法表達式,其結果存儲在標誌寄存器中,以控制代碼序列的跳轉,形成循環。

另外,理解遞歸的關鍵在於理解函數代碼是如何重複調用及迴歸的?以及代碼執行的次序,看下面的實例:

<code>#include <stdio.h>void output(int n){if(n==0)return;printf("遞推 %d\\n",n);output(n-1);printf("迴歸 %d\\n",n);}int main(){output(10);    getchar();return 0;}/<stdio.h>/<code>

執行結果為:

<code>/*遞推 10遞推 9遞推 8遞推 7遞推 6遞推 5遞推 4遞推 3遞推 2遞推 1迴歸 1迴歸 2迴歸 3迴歸 4迴歸 5迴歸 6迴歸 7迴歸 8迴歸 9迴歸 10*//<code>

函數調用了10次,函數體重複了10次,但函數體內的代碼執行的順序在遞推和迴歸階段的執行部分是不相同的,函數體內以遞歸函數語句:output(n-1);為基準,此語句前的代碼在遞推階段執行,此語句後的代碼在迴歸階段執行。遞推時參數和局部變量壓棧,迴歸時參數和局部變量從棧彈出。

上述實例在遞歸函數語句:output(n-1);後如果沒有其它代碼,直接結束,稱為尾遞歸,較容易通過循環去實現。

-End-


分享到:


相關文章: