遞歸是函數直接或間接調用自身的編程技巧。核心要素:
void prn(void) {
printf("C++Builder 2009\n");
prn(); // 無終止條件,需 Ctrl+C 強制結束
}
void prn(int num) {
printf("%d\n", num);
if (num > 0) prn(--num); // 基線:num <= 0 時停止
}
// prn(9) 輸出 9 8 7 ... 0
void revers(char *cs) {
if (*cs) {
revers(cs + 1); // 先遞歸到末尾
putchar(*cs); // 回溯時輸出,實現反序
}
}
// revers("123456789") 輸出 987654321
int factorial(int num) {
if (num == 1) return 1; // 基線
return num * factorial(num - 1); // 遞歸步驟
}
// factorial(5) = 5*4*3*2*1 = 120
void IntToBinary(unsigned num) {
int bit = num % 2;
if (num > 1) IntToBinary(num / 2);
putchar(bit ? '1' : '0'); // 回溯時輸出高位在前
}
// IntToBinary(255) 輸出 11111111
void prn(unsigned n) {
printf("%d: %p\n", n, &n); // A: 進入記錄
if (n < 4) prn(n + 1); // B: 遞歸調用
printf("%d: %p\n", n, &n); // C: 返回記錄
}
// prn(1) 輸出分析見下圖

prn(1),執行 A 輸出第 1 行。n=1 滿足條件,調用 prn(2)(B),輸出第 2 行……以此類推至 n=4。n=4 時 A 執行(第 5 行),條件失效,執行 C(第 5 行)。n=3 的調用點,繼續執行 C(第 6 行)。n=2(第 7 行)、n=1(第 8 行),遞歸結束。每次遞歸都在棧上分配新的棧幀(含參數、局部變量、返回地址),&n 地址各不相同,直觀展示棧增長方向。
| 維度 | 遞歸 | 迭代 |
|---|---|---|
| 代碼簡潔度 | 高(天然匹配分治問題) | 需手動維護狀態 |
| 內存開銷 | O(深度) 棧空間 | O(1) 常數空間 |
| 性能 | 函數調用開銷大 | 通常更快 |
| 適用場景 | 樹/圖遍歷、分治、回溯 | 簡單循環、尾遞歸優化場景 |
-O2/-O3)。