首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言函數巢狀呼叫機制詳解:從原理到階乘平方實戰範例

     編輯:關於C語言

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。

完整範例程式

#include 

long 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;
}

關鍵細節

  1. 函數原型前置宣告:f1 內呼叫 f2 前需見到 f2 宣告(或將 f2 定義置於 f1 之前)。
  2. 資料型別選擇:階乘增長極快,9! = 362880 超過 int 16-bit 範圍,必須用 long(32-bit)。
  3. 遞歸 vs 巢狀呼叫:本例為巢狀(不同函數),遞歸為函數呼叫自身,堆疊增長邏輯相同但終止條件不同。

除錯觀察點

  • 在 f2 設置中斷點,觀察呼叫堆疊:main → f1 → f2。
  • 區域變數 c、k 各自屬於對應堆疊幀,互不干擾。
  • 返回值經由暫存器(EAX/RAX)或堆疊傳回呼叫者。

延伸:遞歸版階乘

long fact_rec(int n) {
    return (n <= 1) ? 1 : n * fact_rec(n - 1);
}

遞歸深度受限於堆疊大小,大數階乘仍建議迭代實作。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved