C 聲明由標識符出發,按運算符優先級解析:
[] (數組) 和 () (函數) 同級,左結合。* (指針) 優先級較低。() 可改變結合順序。
int *(*(*a)())[10]
↑ ↑ ↑ ↑ ↑ ↑
7 6 4 2 1 3 5 (閱讀順序)
a 是標識符。[]/(),看左側 *:指針變量。(*a),進入括號內:a 是指針。():指向函數。*:返回指針。[10]:含 10 元素的數組。int*:指向 int 的指針。結論:a 是函數指針,指向函數,該函數返回指針,指向含 10 個 int* 的數組。
| 聲明 | 含義 |
|---|---|
int *p; | 指向 int 的指針 |
int *p[10]; | 指針數組,10 個指向 int 的指針 |
int (*p)[10]; | 指向含 10 個 int 的數組的指針(二維數組行指針) |
int *p(); | 返回指向 int 指針的函數 |
int (*p)(); | 指向返回 int 函數的指針 |
int **p; | 指向指向 int 指針的指針(二級指針) |
| 運算 | 合法對象 | 含義 | 非法示例 |
|---|---|---|---|
& 取址 | 變量、數組元素、函數 | 獲取地址 | &10, &a+b |
* 解引用 | 指針 | 訪問所指對象 | 對非指針解引用 |
| 賦值 | 同類型指針間 | 拷貝地址 | int* = char* (需轉型) |
+n/-n | 指向數組/字符串的指針 | 移動 n 個元素 | 指向單變量的指針 +1 |
++/-- | 同上 | 移動 1 元素 | 同上 |
- (指針減指針) | 指向同一數組的兩指針 | 元素個數差 | 不同數組指針相減 |
== != < > <= >= | 同一數組指針、或與 NULL/0 | 位置比較 | 無關指針比較 |
int a[5](); — 數組元素不能是函數。int f()(); — 函數不能返回函數(可返回函數指針)。int f()[5]; — 函數不能返回數組(可返回指向數組的指針)。char *const *(*next)();
next 是函數指針 → 函數返回 char *const *(指向常量字符指針的指針)。void (*signal(int, void(*)(int)))(int);
signal 聲明:參數 1 int,參數 2 函數指針 void(*)(int),返回函數指針 void(*)(int)。int (*(*x[3])())[5];
x 是數組[3] → 元素是函數指針 (*x[3])() → 函數返回 (*)[5] → 指向含 5 個 int 的數組的指針。
指針
├── 基礎:&、*、賦值、NULL
├── 數組指針:int *p = a; p+i, *(p+i)
├── 字符串指針:char *s = "lit"; const 保護
├── 二維數組指針:int (*p)[N]; 行偏移自動
├── 函數指針:int (*fp)(int,int); 回調核心
├── 指針函數:int *f(); 返回指針,防懸空
├── 指針數組:int *pa[N]; 字符串表、異構表
├── 二級指針:int **pp; 修改一級指針、argv
└── 複雜聲明:從裡向外,[]()優先於*
malloc 後檢查 NULL,用完 free,置 NULL 防野指針。const char* 接收。int (*p)[N] 或 int *p[],勿用 int**。(*fp) 不可省。typedef 分層簡化:typedef int (*FP)(int); FP fp;。