棧的遞迴呼叫
所謂遞迴,就是程式呼叫自身的過程,它可以把一個大型的,複雜的問題層層轉化為一個與原問題相似的,規模較小的問題來求解,遞迴策略只需要少量的程式碼就可以描述出解題過程中所需要的多次重複計算,大大地減少了程式的程式碼量。
一般來說,遞迴需要有臨界條件:遞迴前進和遞迴返回段。否則,遞迴將無線呼叫,永遠無法結束程式,最後會造成記憶體崩潰。
遞迴作為一種演算法在程式設計語言中被廣泛應用,例如,在數學運算中經常遇到計算自然數和的情況,假設要計算1到n之間的自然數之和,就需要先計算1加2的結果,用這個結果加3再得到一個結果,用新得到的結果加4,以此類推,直到用1~(n-1)之間所有數的和加n,此題就可以用遞迴來解決。
#include<stdio.h>
#include<stdlib.h>
#pragma warning(disable:4996)
int getSum(int n)
{
if(n==1)
return 1;
int temp=get(n-1);
return temp+n;
}
int main()
{
int sum=0;
int n=0;
printf("請輸入n的值:\n");
scanf("%d",&n);
sum=getSum(n);
printf("結果:%d\n",sum);
system ("pause");
return 0;
}
整個遞迴過程中getSum( )函式被呼叫了4次,每次呼叫時,n的值都會減1。當n的值為1時,所有遞迴呼叫的函式都會以相反的順序相繼結束,所有的返回值會進行累加,最終得到的結果是10。
事實上,計算機在執行過程中都是用棧來儲存程式中的變數,函式等,當定義了一個變數,變數入棧,使用完畢後就出棧。在遞迴運算時,函式也不斷地被呼叫進棧,當執行完畢後再依次出棧。接下來就分析上述程式的遞迴呼叫過程。
(1)當傳入引數n=4時,呼叫getSum( )函式,getSum( )函式入棧,執行函式內程式碼;
(2)步驟(1)中再次呼叫getSum( )函式,引數值為3,則getSum( )再次入棧;
(3)步驟(2)中再一次呼叫getSum( )函式,引數值為2,則getSum( )函式再次入棧…以此類推,直到n=1時,getSum( )函式最後一次入棧,此時棧中的情況;
(4)當n=1時,返回值為1,返回給上次函式呼叫,則此次函式呼叫失敗,函數出棧;
(5)當n=2,呼叫的函式得到的出棧的函式返回的值時,就計算出了它這一步呼叫的結果,將結果返回後,本次呼叫結束,函數出棧。
(6)以此類推,直到第一次函式呼叫(n=4時)結束,將計算出的結果返回,然後彈棧。
這就是遞迴在棧中實現的執行和回退過程,回退過程的順序是執行過程中的逆序,下一次呼叫都為上一次呼叫提供需要,顯然這很符合棧的特點,編譯器就是利用這個特點來實現遞迴管理的。當然,對於現在的高階語言來說,這樣的遞迴,以及程式中變數的管理是不需要程式設計師自己來操作的,一切都是由作業系統執行,但讀者也需要理解其原理。