指針是 C 語言的靈魂。本文系統整理指針核心概念、記憶體模型、類型語意、多維/多級指針操作規則與實戰陷阱,構建完整知識體系。
ptr + n 跳過 n * sizeof(type) 位元組*ptr 讀取 sizeof(type) 位元組| 符號 | 名稱 | 語意 |
|---|---|---|
& | 取址運算子 | 取得變數/陣列元素首地址 |
* | 解引用運算子 | 透過地址存取資料 |
arr | 陣列名 | 相當於 &arr[0],無需 & |
&var | 取變數地址 | 指針賦值右值必須是地址 |
**p)int (*p)[3])\0 結尾,隱含一個值為 0 的結束元素char *p = "hello"; 指向唯讀字面量區,不可修改內容char (*p)[2]; // 二維指針:指向含 2 個 char 的陣列 // 解析步驟: // 1. 確認指針維數:p 是一級二維指針 // 2. 方括號操作:p[i] 跳過 i * 2 * sizeof(char) 位元組 // 3. 解引用次數:*(p[i]) 為一維指針,**(p[i]) 為 char 值
int val = 0x1122; char *p3 = (char*)&val; // 一級指針,操作 1 位元組 char **p2 = &p3; // 二級指針,操作 4/8 位元組(地址長度) // p3+1 跳過 1 位元組 // p2+1 跳過 1 個指針大小(4/8 位元組) // *p2 取得 p3 的值(地址) // **p2 取得 val 低位元組
int *p = malloc(2); // 僅分配 2 位元組 *p = 0x12345678; // 非法寫入 4 位元組 → 越界破壞鄰近記憶體 free(p); *p = 0x87654321; // 迷途指針:使用已釋放記憶體 → 未定義行為
unsigned char (*q)(); // 返回 unsigned char、無參函數指針 (*q)(); // 或 q() 調用 // 未傳參時預設傳遞 -1(舊式 K&R 風格,現代 C 應避免)
unsigned char (**p)[3]; // 二級二維指針
int Array3[10] = { ... };
p = (unsigned char(**)[3])Array3; // 強制轉型(教學示範,實務需謹慎)
// p → 二級二維地址
// p+1 → 跳過 1 個指針大小
// *p → 一級二維指針
// *p+1 → 跳過 3 位元組(維度生效)
// **p → 一級一維指針
// ***p → 1 位元組值
// 解引用遞減規則:先降級(多級→一級),再降維(多維→一維→值)
int *p; 而非 int* p;(避免多變數宣告誤解)NULLmalloc 大小與指針類型匹配typedef 簡化複雜指針類型聲明指針精通之路:理解記憶體模型 → 掌握類型語意 → 熟練多維/多級操作 → 培養防禦性習慣。反覆實作、畫圖驗證,方能化險夷為夷途。