許多學習者對指標產生恐懼,本質上是對「變數儲存模型」與「型別解讀機制」理解不足。就像暈車源於前庭系統過度敏感,暈指標源於對電腦如何組織資料缺乏直觀認知。本文從記憶體基礎模型出發,層層遞進建立正確心智模型。
int a = 10;
int *p;
p = &a;
關鍵認知:
| 特性 | 常數 (Literal/Symbolic) | 變數 |
|---|---|---|
| 儲存位置 | 程式碼段/立即數 | 資料段/堆疊/堆積 |
| 可修改性 | 不可修改 | 可讀可寫 |
| 字串常數 | `char *str = "abc"` 指向唯讀區 | `char str[] = "abc"` 可修改 |
// 測試 1:型別轉換與記憶體解讀
char ch = 'a';
int a = (int)ch;
printf("%d %c\n", a, ch); // 輸出:97 a
// 測試 2:指標算術與型別大小
int addr = 0x123456;
int *p = (int*)addr;
// p 儲存位址 0x123456,*p 解讀該位址處 4 bytes 為 int
// 測試 3:巨集替換非變數
#define PI 3.14
int a = PI; // 合法:展開為 3.14,隱式轉 int → 3
printf("%d\n", PI); // 錯誤:%d 期望 int,實傳 double
PI = 1.85; // 錯誤:常數不可賦值
// 測試 4:字串常數不可修改
char *str = "abcdef";
printf("%s\n", str); // 正常
*str = "fedcba"; // 錯誤:嘗試修改唯讀記憶體 → 段錯誤
str[2] = 'C'; // 錯誤:同樣導致未定義行為
char a[6] = {'A','B','C','D','E','F'};
位址: 0x28c3 0x28c4 0x28c5 0x28c6 0x28c7 0x28c8
值: 'A' 'B' 'C' 'D' 'E' 'F'
偏移: 0 1 2 3 4 5
char *pc; pc + 1 → 位址 + 1 (sizeof(char))
int *pi; pi + 1 → 位址 + 4 (sizeof(int))
struct Node *pn; pn + 1 → 位址 + sizeof(Node)
char a[3][4]; // 3 列 4 行
a + 1 → 跳過一整列 (4 * sizeof(char) = 4 bytes)
&a[0][0] + 5 → 第 2 列第 1 行元素
指標不是魔法,而是記憶體位址的直接操作介面。掌握「資料在記憶體中如何組織」與「型別如何賦予位元含義」這兩個核心,指標就會從恐怖傳說變成得心應手的工具。