前言
C 語言的宣告語法以「聲明模仿使用」聞名,但複雜宣告(如函數指標陣列、指標函數等)常讓人抓狂。本文介紹經典的「右左法則」(Clockwise/Spiral Rule)與優先級規則,助你輕鬆破解任何宣告。
核心原則:優先級規則
- 從**變數名稱**開始。
- 優先處理**右邊**的 `()`(函數)與 `[]`(陣列)。
- 再處理**左邊**的 `*`(指標)。
- 最後結合基礎型別(`int`、`char` 等)。
- `const`/`volatile` 修飾最近的型別或指標。
右左法則口訣
「從變數名出發,向右找 `()` 或 `[]`,向左找 `*`,循環直到基礎型別。」
實戰範例解析
範例 1:int * (*next)();
- 從
next 開始。
- 右邊有 `()` → 「函數」。
- 左邊有 `*` → 「指向...的指標」。
- 右邊無 `[]`,左邊無 `*`,基礎型別 `int`。
- 結果:
next 是一個**函數指標**,指向**回傳 `int*` 的函數**。
範例 2:char * (*c[10])(int **p);
- 從
c 開始。
- 右邊 `[10]` → 「長度 10 的陣列」。
- 右邊 `()` → 「函數,參數為 `int**`」。
- 左邊 `*` → 「指向...的指標」。
- 基礎型別 `char`。
- 結果:
c 是一個**長度 10 的陣列**,每個元素是**函數指標**,指向**參數為 `int**`、回傳 `char*` 的函數**。
常見陷阱與非法宣告
- 函數不能回傳函數或陣列:`function()()`、`function()[]` 非法。
- 但可回傳指標:`int (*function[])()` 合法(函數指標陣列)。
- `typedef` 簡化複雜宣告:
typedef char * (*FunPtr)(int**); 後直接用 FunPtr c[10];。
實用技巧
- 善用 typedef:分層定義,如先定義函數指標型別,再定義陣列。
- cdecl 工具:線上 cdecl.org 可互轉宣告與英文說明。
- 編譯器報錯:嘗試編譯,錯誤訊息常能提示正確寫法。
總結
掌握優先級規則與右左法則,配合 typedef 分解複雜類型,任何 C 宣告都能迎刃而解。這是系統程式設計師的必備基本功。