C 不允許嵌套定義函數,但允許嵌套調用:
main() {
a(); // 調用 a
}
a() {
b(); // a 中調用 b
}
b() { ... } // 執行完返回 a,a 完返回 main
執行流程:main → a → b → 返回 a → 返回 main。每層調用保存斷點(返回地址),棧幀管理局部變量。
函數直接/間接調用自身。必須有終止條件(基例),否則無限遞歸導致棧溢出。
int factorial(int n) {
if (n <= 1) return 1; // 基例
return n * factorial(n - 1); // 遞歸步驟
}
factorial(3)
→ 3 * factorial(2)
→ 2 * factorial(1)
→ 1 (基例返回)
→ 2 * 1 = 2
→ 3 * 2 = 6
| 特性 | 嵌套調用 | 遞歸調用 |
|---|---|---|
| 函數關係 | 不同函數 | 同一函數 |
| 棧幀 | 每層不同函數幀 | 同函數多實例幀 |
| 終止條件 | 自然結束 | 必須顯式基例 |
| 典型用途 | 模塊分解 | 分治算法、樹遍歷、數學定義 |
若遞歸調用是函數最後動作,編譯器可優化為迴圈(復用棧幀)。C 編譯器支持程度不一,不應依賴。
嵌套調用是模塊化編程常態,遞歸是解決特定問題的強大工具,二者皆依賴棧機制管理調用上下文。