指針與數組是 C 語言核心也是難點。本文通過類比、圖解、代碼驗證,系統梳理數組名、指針數組、數組指針、二維數組的本質區別與使用技巧。
int a[3] = {1,2,3};
&a[0],類型 int*。a+1 偏移 sizeof(int)。int(*)[3]。&a+1 偏移 sizeof(int[3]) = 12 字節。int *p = a; 合法;int (*p)[3] = &a; 合法;int *p = &a; 類型不匹配。定義:int *ptr[3]; — 數組,元素是 int*。
int x=5; ptr[0]=&x; ptr[1]=&a[2];
*ptr[0] → 5; *ptr[1] → 3;
理解口訣:先看 [],說明是數組;再看元素類型 int*。
定義:int (*ptr)[3]; — 指針,指向 int[3] 類型數組。
int (*ptr)[3] = &a; // 正確
(*ptr)[0] → 1; // 先解引用得數組,再取下標
類比:int *p = &x; *p → 5。數組指針同理:*ptr 得到數組,(*ptr)[i] 取元素。
本質:一維數組的數組,元素類型為 int[3]。
int a[3][3] = {{1,2,3},{4,5,6},{7,8,9}};
int(*)[3],等價 &a[0]。a+1 指向第二行,偏移 12 字節。int(*)[3][3],偏移 36 字節。int (*ptr)[3] = a; // 正確,a 為首行地址。ptr[i][j] 等價 *(*(ptr+i)+j)。| 表達式 | 含義 | 類型 |
|---|---|---|
| a | 首行地址 | int(*)[3] |
| a[0] | 首行首元素地址 | int* |
| &a[0][0] | 首元素地址 | int* |
| a+1 | 第二行地址 | int(*)[3] |
| *(a+1) | 第二行首元素地址 | int* |
| *(*(a+1)+2) | a[1][2] 值 | int |
int *p[N]。int (*p)[N]。理解指針與數組的關鍵在於「類型決定步長」。畫內存圖、寫測試代碼驗證 sizeof 和地址差值,是掌握的最快途徑。