C 語言聲明語法以「聲明形式模仿使用形式」為哲學,但導致優先級極其複雜。本文系統梳理指針陣列與數組指針區別、const 修飾規則、結構體/聯合體/枚舉聲明細節,助你破解聲明迷宮。
「聲明形式模仿使用形式」:int *p[4] 使用時寫 *p[i],形式相似。
代價:15 級優先級,無法直觀左到右閱讀。
int *p[5]; // 指針陣列:本質是陣列,元素是 int*
int (*p)[5]; // 數組指針:本質是指針,指向 int[5]
| 聲明 | 步驟 1 | 步驟 2 | 結論 |
|---|---|---|---|
int *p[5] | p[5] → 陣列 | int * → 元素類型 | 5 個 int 指針的陣列 |
int (*p)[5] | (*p) → 指針 | int [5] → 指向類型 | 指向 5 元素 int 陣列的指針 |
關鍵:[] 優先級高於 *,括號改變結合順序。
const int *p; // p 可變,*p 不可變(const 在 * 左,近數據)
int const *p; // 同上,等價
int *const p; // p 不可變,*p 可變(const 在 * 右,近指針)
口訣:const 貼近誰就修飾誰。
struct { int x; int y; } pt1, pt2; // 定義兩個變量
缺點:無法復用類型定義新變量。
struct Point { int x; int y; };
struct Point pt1, pt2, pt3; // 復用
typedef struct { int x; int y; } Point;
Point pt1, pt2; // 簡潔,但失去「是結構體」的語義提示
struct Flags {
unsigned int inactive : 1;
unsigned int : 1; // 無名填充
unsigned int test : 6;
short pid_id;
struct Flags *next;
};
int/unsigned int/signed intunion BitTag {
uint8_t state;
struct {
uint8_t bit_1 : 4;
uint8_t bit_2 : 4;
} BIT;
};
enum Color { RED, GREEN=5, BLUE }; // RED=0, GREEN=5, BLUE=6
#define:調試器可見、類型檢查、作用域限制()、[] 先處理*、類型修飾符int *(*p[5])(); // p 是陣列[5] → 元素是指針 → 指向函數 → 返回 int*
下篇將深入函數指針、複雜聲明實戰解析、cdecl 工具使用技巧。