C 語言不支援函數定義巢狀(函數內定義函數),但支援函數呼叫巢狀:函數 A 呼叫函數 B,B 又呼叫 C,形成呼叫鏈。本文解析堆疊幀切換流程,並以計算 S = 2²! + 3²! 為例示範多層呼叫實作。
main() → f1(i) → f2(k) → return → f1 → return → main
main 呼叫 f1 → f1 呼叫 f2 → f2 完成返回 f1 斷點 → f1 完成返回 main 斷點。main 傳 i 給 f1,f1 計算 k=i*i 傳給 f2。#includelong f2(int q) { // 計算階乘 q! long c = 1; for (int i = 1; i <= q; i++) c *= i; return c; } long f1(int p) { // 計算 (p²)! int k = p * p; // 平方 return f2(k); // 巢狀呼叫 } int main(void) { long s = 0; for (int i = 2; i <= 3; i++) s += f1(i); // 2²! + 3²! = 4! + 9! = 24 + 362880 = 362904 printf("s=%ld\n", s); return 0; }
f1 內呼叫 f2 前需見到 f2 宣告(或將 f2 定義置於 f1 之前)。9! = 362880 超過 int 16-bit 範圍,必須用 long(32-bit)。f2 設置中斷點,觀察呼叫堆疊:main → f1 → f2。c、k 各自屬於對應堆疊幀,互不干擾。EAX/RAX)或堆疊傳回呼叫者。long fact_rec(int n) {
return (n <= 1) ? 1 : n * fact_rec(n - 1);
}
遞歸深度受限於堆疊大小,大數階乘仍建議迭代實作。