理解 C 複雜聲明(如函數指標、陣列指標、指標陣列)的關鍵在於掌握聲明的優先級解析規則。依據《Expert C Programming》(《C專家編程》),規則如下:
() 括起的部分;() 表示函數,[] 表示陣列;* 表示「指向…的指標」。const/volatile 後面緊跟類型說明符(如 int、long)時,作用於該類型;否則作用於其左側緊鄰的指標星號 *。char * const * (*next)();char * const * (*next)();
next —— 聲明名字。(*next) —— next 是一個指標。(*next)() —— next 是一個函數指標(指向函數的指標)。* (*next)() —— 該函數返回一個指標。char * const —— 指向 char 型的常量指標(指標本身不可修改指向)。結論:next 是一個函數指標,指向的函數返回一個指向字符型常量的指標。
int (*foo())[];int (*foo())[];
foo —— 名字。foo() —— foo 是一個函數。(*foo()) —— 該函數返回一個指標。(*foo())[] —— 返回的指標指向一個陣列。int —— 陣列元素類型為 int。結論:foo 是一個函數,該函數返回一個指向整型陣列的指標。
cdecl 工具與右左法則除手動推導外,可使用 cdecl(C Declaration Parser)工具輔助,或掌握「右左法則」:
、()),再向左找前綴(*),遇到括號則作為一個整體處理。| 聲明 | 含義 |
|---|---|
int *p[10]; | p 是指標陣列(含10個 int*) |
int (*p)[10]; | p 是陣列指標(指向含10個 int 的陣列) |
int (*p)(int); | p 是函數指標(指向參數為 int、返回 int 的函數) |
int *p(int); | p 是函數(返回 int*) |
int **p; | p 是二級指標(指向 int* 的指標) |
const int *p; | p 是指向常量整數的指標(不可通過 p 修改值) |
int *const p; | p 是常量指標(指標本身不可修改指向) |
const int *const p; | p 是指向常量整數的常量指標 |
掌握聲明優先級規則,配合「從名字起步、按優先級遞進」的系統化分析方法,即可輕鬆解讀最晦澀的 C 聲明。實務中建議:善用 typedef 分層簡化複雜類型,提升代碼可讀性與可維護性。