指針類型 = 基類型 + 指針層級。例如:
int* p → 指向 int
int** p → 指向指向 int 的指針
int (*pa)[3] → 指向含 3 個 int 的數組
int (*pf)() → 指向返回 int 的無參函數
三大核心屬性:
1. 指針自身類型(去掉變量名)。
2. 指向對象類型(去掉一級 *)。
3. 指針算術運算步長 = sizeof(指向類型)。
32 位系統下普通指針佔 4 字節;但指向成員指針大小不固定(4/8/12/16 字節),視繼承/虛函數複雜度而定。& 取地址(針對對象),* 取內容(針對地址),互為逆操作。
int a[3][4][5] 實為:含 3 個元素的數組,每元素含 4 個元素的數組,再每元素含 5 個 int。
元素個數必須編譯期常量(C99 支持變長數組)。
數組名可獲取首元素地址(int* p = a 等價 &a[0])。
下標操作本質:a[i] ≡ *(a+i) ≡ *(i+a) ≡ i[a]。負下標 a[-1] 合法但危險。
同一數組指針相減得元素間距;不同數組指針相減無意義。
從標識符出發,按運算符優先級結合:
[] 和 () 優先於 *。
例 int* (*a[5])(int, char*):
a → [5] → 數組 5 元素 → * → 指針 → (int, char*) → 函數參數 → int* → 返回值。
即:a 是含 5 個函數指針的數組,函數接受 int 和 char*,返回 int*。
善用 typedef 分層簡化:
typedef int* (*PF)(int, char*); PF a[5];
const/volatile 位置規則:
const int* / int const* → 指向常量 int(int 不可改)。
int* const → 常量指針(指針不可改)。
建議採用「const 後置」風格(int const*),配合 typedef 含義不變。
... 與 va_listprintf 原型:int printf(const char* format, ...)。
標準頭文件 <stdarg.h> 提供宏:
va_start(ap, last_fixed)、va_arg(ap, type)、va_end(ap)、va_copy。
實現自定義錯誤處理:
void error(const char* fmt, ...) {
va_list ap;
va_start(ap, fmt);
fprintf(stderr, "error: ");
vfprintf(stderr, fmt, ap);
va_end(ap);
fprintf(stderr, "\n");
exit(1);
}
調用約定差異:
__stdcall(被調用者清棧,固定參數)vs __cdecl(調用者清棧,可變參數)。
重載解析中 ... 匹配優先級最低,可用於 SFINAE 技巧。
花一個月精讀,C 語言核心難點將迎刃而解。