在函數的執行過程中無可避免的會涉及到參數存儲的問題,而函數的參數是存儲棧中,棧最大的特點是“先進后出”,之前創建的參數在當前已經被其他變量覆蓋,無法訪問,但是是存在的,不能認為已經被銷毀了。函數在被遞歸調用時讓人疑惑的主要原因也因為參數的存儲引起的。
下面的程序可以很好的解釋遞歸的過程中參數的存儲以及使用過程。
#include<stdio.h> void binary_to_assic(unsignde int value ){ unsigned int a=value/10; if(a!=0) binaray_to_assic(a);//遞歸調用函數的過程就是將參數入棧的過程 putchar(value%10+'0'); //使用參數的過程就是講參數出棧的過程 } void main(){ binaray_to_assic(4267); }
binary_to_assic()函數在執行過程中不斷的對自身進行遞歸調用,將參數“value”壓棧,壓棧完成后從上到下的順序是:4、42、426、4267。
接下來putchar語句會對變量進行引用,按照變量存儲在棧中的順序依次處理。所以最終會打印出:4267。
具體的函數流程能幫助我們進一步理解遞歸:
binaray_to_assic(4267)----binaray_to_assic(426)----binaray_to_assic(42)----binaray_to_assic(4) binaray_to_assic(4267){ binaray_to_assic(426){ binaray_to_assic(42){ binaray_to_assic(4){ binaray_to_assic(0)//結束遞歸 putchar(4%10) } putchar(42%10) } putchar(426%10) } putchar(4267%10) }
當開始執行第4級調用時,a的值為0,if判斷不再滿足,這時候不在繼續調用binary_to_assic()函數,第4級調用則繼續執行其后面的語句:putchar();此時第4級調用結束,把控制權返回給該函數的調用函數,也就是第3級調用函數。依次類推。
遞歸的基本原理:
1 每一次函數調用都會有一次返回.當程序流執行到某一級遞歸的結尾處時,它會轉移到前一級遞歸繼續執行.
2 遞歸函數中,位於遞歸調用前的語句和各級被調函數具有相同的順序.如打印語句 #1 位於遞歸調用語句前,它按照遞歸調用的順序被執行了 4 次.
3 每一級的函數調用都有自己的私有變量.
4 遞歸函數中,位於遞歸調用語句后的語句的執行順序和各個被調用函數的順序相反.
5 雖然每一級遞歸有自己的變量,但是函數代碼並不會得到復制.
6 遞歸函數中必須包含可以終止遞歸調用的語句
關於遞歸的講解《C和指針》講解的很細致,有興趣的可以看看。