函數指針指向代碼區(指令內存),普通指針指向數據區。函數名本身就是函數入口地址。
返回類型 (*指針變量名)(參數列表); // 例:void (*pf)(); // 指向 void f() 類型函數
void open() { printf("open\n"); }
void print() { printf("print\n"); }
void exit() { printf("exit\n"); }
int main() {
// 1. 單個函數指針
void (*pf)() = open;
(*pf)(); // 調用 open()
// 2. 函數指針數組:菜單/狀態機核心
void (*pfs[])() = {open, print, exit};
for (int i = 0; i < 3; i++)
(*pfs[i])(); // 依次調用 open, print, exit
}
從變量名開始,先右後左,遇括號優先處理括號內。
| 聲明 | 含義 | 讀法步驟 |
|---|---|---|
void (*getInterrupt(int no))(); | 函數聲明:參數 int,返回指向 void() 的指針 | getInterrupt → (int no) → * → () → void |
void setInterrupt(int no, void (*pf))(); | 函數聲明:參數 int 和函數指針,返回 void | setInterrupt → (int no, *pf()) → void |
LRESULT (*lpfnWndProc)(HWND, UINT, WPARAM, LPARAM); | 變量聲明:指向窗口過程函數的指針 | lpfnWndProc → * → (HWND...) → LRESULT |
int cmp_int(const void *a, const void *b) {
return *(int*)a - *(int*)b;
}
qsort(arr, n, sizeof(int), cmp_int); // 標準庫回調
typedef void (*StateHandler)(Event*);
StateHandler state_table[] = {
[IDLE] = handle_idle,
[RUNNING] = handle_running,
[ERROR] = handle_error
};
// 運行時動態分發
state_table[current_state](&event);
// 宿主程序
typedef struct { const char *name; void (*init)(); void (*run)(); } Plugin;
Plugin plugins[MAX_PLUGINS];
// 插件實現(單獨編譯)
void my_plugin_init() { ... }
void my_plugin_run() { ... }
Plugin my_plugin = {"MyPlugin", my_plugin_init, my_plugin_run};
typedef struct {
void (*draw)(Shape*);
double (*area)(Shape*);
} ShapeVTable;
typedef struct {
ShapeVTable *vptr;
// 數據成員...
} Shape;
// 繼承:子類填寫自己的 vtable
ShapeVTable circle_vtable = {circle_draw, circle_area};
Shape circle = {&circle_vtable, ...};
// 多態調用
shape->vptr->draw(shape);
// 不用 typedef void (*signal(int sig, void (*handler)(int)))(int); // 使用 typedef typedef void (*SigHandler)(int); SigHandler signal(int sig, SigHandler handler); // 清晰得多
(*pf)() 或 pf() 均可,前者更明確if (pf) (*pf)();int *f()(返回指針的函數)vs int (*f)()(函數指針)