本書雖薄,卻直擊指針核心難點,適合初學者建立正確心智模型。第一章重點涵蓋 size_t 正確使用、指針算術運算本質、const 與指針的四種組合語義。以下整理關鍵結論並附可編譯驗證代碼。
size_t 是 sizeof 運算符的返回類型,保證能容納最大對象字節數。打印時必須用 %zu (C99) 或 %lu + 強轉,否則有符號解讀會導致誤判。
void size_t_test() {
size_t t1 = (size_t)-1; // 最大值 0xFFFFFFFF / 0xFFFFFFFFFFFFFFFF
size_t t2 = 1;
printf("t1: %zu t2: %zu\n", t1, t2); // 正確輸出
// 錯誤示範:printf("%d", t1) → 輸出 -1
}
p + n 等價於 (char*)p + n * sizeof(*p)。指針類型決定步長,而非指針本身大小。
void pointer_add_sub_test() {
int i = 1; int *pi = &i; // sizeof(int) = 4
char c = 'a'; char *pc = &c; // sizeof(char) = 1
printf("pi: %p pi+1: %p diff=%td\n", (void*)pi, (void*)(pi+1), (pi+1)-pi); // diff=1
printf("pc: %p pc+1: %p diff=%td\n", (void*)pc, (void*)(pc+1), (pc+1)-pc); // diff=1
// 但地址增量:pi+1 比 pi 大 4 字節;pc+1 比 pc 大 1 字節
}
| 聲明 | 口訣 | 可修改指針值 | 可修改指向內容 | 典型用途 |
|---|---|---|---|---|
const int *pint const *p | const 修飾 *p → 指向常量的指針 | ✅ | ❌ | 函數參數 const char *str 保護只讀 |
int * const p | const 修飾 p → 常量指針(指針本身不可變) | ❌ | ✅ | 固定緩衝區基址 |
const int * const p | 雙重 const | ❌ | ❌ | 只讀查表、字符串常量 |
void const_to_pointer() {
int v1 = 1, v2 = 2;
const int cv = 3;
// 1. 指向常量的指針
const int *p1 = &v1; // OK
p1 = &v2; // OK:改指向
// *p1 = 10; // 編譯錯誤:不可通過 p1 修改值
v1 = 10; // OK:通過原變量修改
// 2. 常量指針(指針本身不可變)
int * const p2 = &v1; // 必須初始化
*p2 = 20; // OK:修改值
// p2 = &v2; // 編譯錯誤:不可改指向
// 3. 指向常量的常量指針
const int * const p3 = &cv; // 雙重保護
}
size_t 專為無符號尺寸設計,打印用 %zu。const 位置決定語義:靠近類型修飾「被指內容」;靠近變量名修飾「指針本身」。這三點是指針編程的基石,建立清晰心智模型後,後續多級指針、函數指針、指針數組等進階主題將不再迷茫。