今天說的是棧與遞歸的關系,函數的遞歸調用和普通函數調用是一樣的。當程序執行到某個函數時,將這個函數進行入棧操作,在入棧之前,通常需要完成三件事。
1、將所有的實參、返回地址等信息傳遞給被調函數保存。
2、為被調函數的局部變量分配存儲區。
3、將控制轉移到北調函數入口。
當一個函數完成之后會進行出棧操作,出棧之前同樣要完成三件事。
1、保存被調函數的計算結果。
2、釋放被調函數的數據區。
3、依照被調函數保存的返回地址將控制轉移到調用函數。
上述操作必須通過棧來實現,即將整個程序的運行空間安排在一個棧中。每當運行一個函數時,就在棧頂分配空間,函數退出后,釋放這塊空間。所以當前運行的函數一定在棧頂。
(注:摘自嚴蔚敏等人的數據結構c語言版)
接下來我們來觀察一個簡單的遞歸。
#include <stdio.h> void recurrence(int num) { if ( num < 0 ) return; printf("%d\n", num); recurrence(num - 1);
printf("%d\n", num);
} int main(void) { recurrence(5); return 0; }
程序每次運行到recurrence()函數時都會進入這個這個函數,直到num為0時返回,返回之后會接着運行recurrence()后面的代碼,箭頭代表函數控制權轉移,請看圖示。