天天看點

C語言函數遞歸

C語言函數遞歸

遞歸概念

在C語言中,函數調用可以從main()函數,其他函數或同一函數本身進行。遞歸函數定義如下:一個函數調用函數自身稱為遞歸函數。應該非常小心地使用遞歸函數,因為當一個函數自己調用它進入無限循環時。當函數進入無限循環時,函數執行永遠不會完成。我們應該定義退出函數調用的條件,以便遞歸函數終止。當一個函數被自己調用時,第一個調用仍在執行中,直到調用最後一個調用。每次調用函數調用時,該函數都會将執行控件傳回到上一個函數調用。舉個 栗子 ,你用你手中的鑰匙打開一扇門,結果卻發現前方還有一扇門,緊接着你又用鑰匙打開了這扇門,然後你又看到一扇門...但是當你開到某扇門時,發現前方是一堵牆無路可走了,你選擇原路傳回——這就是遞歸,如下圖即使是遞歸。

C語言函數遞歸

階乘是基斯頓·卡曼(Christian Kramp,1760~1826)于 1808 年發明的運算符号,是數學術語。一個正整數的階乘(factorial)是所有小于及等于該數的正整數的積,并且0的階乘為1。自然數n的階乘寫作n!。1808年,基斯頓·卡曼引進這個表示法。亦即n!=1×2×3×...×n。階乘亦可以遞歸方式定義:0!=1,n!=(n-1)!×n。

C語言函數遞歸

可以看到,return fact_iter(n- 1, n* result)僅傳回遞歸函數本身,n- 1和n* result在函數調用前就會被計算,不影響函數調用。尾遞歸調用時,如果做了優化,棧不會增長,是以,無論多少次調用也不會導緻棧溢出。

C語言函數遞歸

尾言

使用遞歸函數的優點是邏輯簡單清晰,缺點是過深的調用會導緻棧溢出。針對尾遞歸優化的語言可以通過尾遞歸防止棧溢出。尾遞歸事實上和循環是等價的,沒有循環語句的程式設計語言隻能通過尾遞歸實作循環。标準的解釋器沒有針對尾遞歸做優化,任何遞歸函數都存在棧溢出的問題。