系統講解函數指針聲明、調用、回調函數、動態排序策略、函數指針作返回值構建函數表驅動,附完整可運行代碼示例。
// 聲明:返回類型 (*指針名)(參數列表)
int (*p)(int, int) = sum; // 指向 int sum(int,int)
// 調用兩種等價形式
p(3, 5); // 直接調用
(*p)(3, 5); // 解引用調用
// 通用搜索函數,接受回調處理匹配項
void search(Student *stu, void (*callback)(Student*)) {
if (stu->score >= 90) callback(stu);
}
// 具體回調實現
void addString(Student *s) {
strcat(s->name, "高富帥");
}
// 使用
search(&stu[i], addString);
核心:將「做什麼」作為參數傳遞,實現算法與業務邏輯分離。
// 比較函數類型
typedef int (*CompareFn)(Student*, Student*);
// 具體策略
int cmpAgeAsc(Student *a, Student *b) { return a->age > b->age; }
int cmpScoreDesc(Student *a, Student *b) { return a->score < b->score; }
// 通用排序
void sortStudent(Student *arr, int n, CompareFn cmp) {
// 冒泡排序框架
for (int i = 0; i < n-1; i++)
for (int j = 0; j < n-1-i; j++)
if (cmp(arr+j, arr+j+1)) swap(arr+j, arr+j+1);
}
// 運行時切換策略
sortStudent(stu, 5, cmpAgeAsc); // 年齡升序
sortStudent(stu, 5, cmpScoreDesc); // 成績降序
typedef int (*MathFn)(int, int);
typedef struct { char name[20]; MathFn fn; } FnEntry;
MathFn getFnByName(FnEntry *table, int n, char *name) {
for (int i = 0; i < n; i++)
if (strcmp(table[i].name, name) == 0)
return table[i].fn;
return NULL;
}
// 函數表
FnEntry table[] = {
{"add", add}, {"sub", sub}, {"mul", mul}, {"div", div}
};
// 動態調用
MathFn fn = getFnByName(table, 4, "add");
if (fn) printf("%d", fn(3, 5)); // 8
typedef void (*StateHandler)(Event*);
StateHandler stateTable[STATE_COUNT][EVENT_COUNT] = {
{handleIdle, handleStart, ...},
{handleRun, handleStop, ...},
...
};
// 事件循環
while (running) {
Event e = getEvent();
StateHandler h = stateTable[currentState][e.type];
if (h) h(&e);
}
| 模式 | 解決問題 | 關鍵詞 |
|---|---|---|
| 回調 | 異步通知/擴展點 | 參數化行為 |
| 策略 | 算法族運行時切換 | 開閉原則 |
| 函數表 | 字符串動態分發 | O(1)查找 |
| 狀態機 | 複雜狀態轉換 | 表驅動 |
函數指針是 C 語言實現多態、依賴倒置、插件架構的核心機制,掌握它即掌握 C 語言面向對象設計的精髓。