C Primer Plus 第九章 大二第二学期 第二天学习
9.3.3 尾遞歸
最簡單的遞歸形式是把遞歸調用置于函數的末尾,即正好在return語句之前。這種形式的遞歸被稱為尾遞歸
因為遞歸調用在函數的末尾,
尾遞歸是最簡單的遞歸形式,因為它相當于循環
下面要介紹的程序示例中,分別用循環和尾遞歸計算階乘,一個正整數的階乘是從1到該整數的所有整數的乘積
例如,3的階乘(寫 作3!)是1×2×3。另外,
0!等于1
負數沒有階乘。
程序清單9.7中,第1個 函數使用for循環計算階乘,第2個函數使用遞歸計算階乘。
/*輸入一個數,并計算這個數的階乘*/#include "stdio.h"long fact(int n); long rfact(int n); int main() {int num;printf("This program calculattes factorials.\n");printf("Please enter a value in the range 0-12 (q to quit): \n");while(scanf("%d",&num) == 1){if(num<0)printf("NO negaticve number.\n");else if(num>12)printf("Keep input under 13");elseprintf("loop: %d factorial = %ld \n", num,fact(num));//循環printf("loop: %d recursion = %ld \n",num,rfact(num));//遞歸}return 0; }long fact(int n) {long ans;for(ans = 1;n>1;n--)ans*=n;return ans;}long rfact( int n) {///10! = 10*9!=10*9*8!/// rfact(10) = 10rfact(9)........long ans;if(n>0)ans = n*rfact(n -1);elseans = 1;return ans;}測試驅動程序把輸入限制在0–12,.因為12!已經快接近5億,而13!比62億還大,已超過我們系統中long 類型能表示的范圍。要計算超過12的階乘,必須使用能表示更大范圍的類型,如 double和long long.
使用循環的函數把ans初始化為1,然后把ans與從n-2的所有遞減整數相乘。根據階乘的公式,根據階乘的公式,還應該乘以1,但是這并不會改變結果
現在考慮使用遞歸的函數。該函數的關鍵是n! = n×(n-1)!。可以這樣做 是因為(n-1)!是n-1~1的所有正整數的乘積。因此,n乘以n-1就得到n的階乘。 階乘的這一特性很適合使用遞歸。如果調用函數rfact(),rfact(n)是 n*rfact(n- 1)。因此,通過調用 rfact(n-1)來計算rfact(n),如程序清單9.7中所示。當 然,必須要在滿足某條件時結束遞歸,可以在n等于0時把返回值設為1。 程序清單9.7中使用遞歸的輸出和使用循環的輸出相同。注意,雖然 rfact()的遞歸調用不是函數的最后一行,但是當n>0時,它是該函數執行的最 后一條語句,因此它也是尾遞歸
循環和遞歸的選擇:一般而言,選擇循環比較好,首先,
每次遞歸都會創建一組變量,所以遞歸使用的內存更多,而且每次遞歸調用都會把創建的一組新變量放在棧中。遞歸調用的數量受限于內存空間。其次由于每次函數調用要花費一定的時間,所以遞歸的執行速度較慢
演示程序的目的:因為尾遞歸是遞歸中最簡單的形式,比較容易理解,在某些情況下,不能用簡單的循環來代替遞歸
看到9.3.4
總結
以上是生活随笔為你收集整理的C Primer Plus 第九章 大二第二学期 第二天学习的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: word中删除水平线(分割线)的方法
- 下一篇: Mac上如何利用itunes恢复存放在移