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

C 語言函數指針完全指南:語法、陣列應用與回調模式

     編輯:關於C語言

C 語言函數指針完全指南

在 C 語言中,函數名本質上就是指向函數程式碼區的指標。掌握函數指標可實現回調、狀態機、策略模式等進階設計模式,是系統級開發的核心技能。

函數指標宣告語法

返回類型 (*指標變數名)(參數類型列表);

範例:int (*calculate)(int, int); 宣告一個指向「接受兩 int 回傳 int」函數的指標。

基本使用範例

#include <stdio.h>

int add(int n, int m) { return n + m; }
int sub(int n, int m) { return n - m; }

int main() {
    int n = 10, m = 5;
    int (*calculate)(int, int);  // 宣告函數指標

    calculate = add;             // 指向 add
    printf("add: %d\n", calculate(n, m));  // 15

    calculate = sub;             // 指向 sub
    printf("sub: %d\n", calculate(n, m));  // 5

    return 0;
}

注意:呼叫時 calculate(n, m) 與 (*calculate)(n, m) 等價,前者為語法糖。函數指標嚴格檢查簽名(回傳型別、參數型別、參數個數)必須完全一致。

函數指標陣列:表驅動程式設計

將多個同簽名函數放入陣列,配合枚舉索引,實現「資料驅動邏輯」。

#include <stdio.h>

typedef enum { DUMP, SECOND_CHANCE, MARRIAGE } ResponseType;

typedef struct {
    const char* name;
    ResponseType type;
} Response;

void dump(Response r) { printf("dump %s\n", r.name); }
void second_chance(Response r) { printf("second_chance %s\n", r.name); }
void marriage(Response r) { printf("marriage %s\n", r.name); }

int main() {
    Response rs[] = {
        {"Mike", DUMP},
        {"Luis", SECOND_CHANCE},
        {"Matt", SECOND_CHANCE},
        {"William", MARRIAGE}
    };

    void (*replies[])(Response) = { dump, second_chance, marriage };

    for (int i = 0; i < 4; ++i) {
        replies[rs[i].type](rs[i]);  // 根據類型直接調用對應函數
    }
    return 0;
}

輸出:

dump Mike
second_chance Luis
second_chance Matt
marriage William

進階應用場景

場景說明關鍵技術
回調函數庫函數接受使用者函數指標,事件發生時調用qsort 比較函數、訊號處理 signal()
狀態機每個狀態對應一個處理函數,狀態轉移即修改函數指標函數指標陣列 + 狀態枚舉
策略模式執行時動態切換演算法(排序、壓縮、加密)結構體內嵌函數指標
動態載入dlopen/dlsym 取得函數位址賦給函數指標外掛架構、熱更新

常見錯誤與避坑指南

  1. 宣告混淆:int *func() 是「回傳指標的函數」,非函數指標。必須加括號 int (*func)()
  2. 隱式轉換:嚴禁將不匹配簽名的函數賦值,雖然編譯器可能只警告,但運行時行為未定義
  3. NULL 指標調用:調用前務必檢查 if (func_ptr)
  4. 呼叫約定不匹配:跨語言/動態庫時需確認 __cdecl, __stdcall 等一致

typedef 簡化宣告

typedef int (*BinaryOp)(int, int);  // 定義型別別名

BinaryOp ops[] = { add, sub, mul, div };
int calculate(BinaryOp op, int a, int b) { return op(a, b); }

使用 typedef 大幅提升可讀性,特別是函數指標作為參數或回傳值時。

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