指針與數組是 C 語言靈魂雙子星。本文系統梳理一維/多維數組指針、指針運算、字符串指針的定義、賦值、訪問與常見陷阱,並配圖解記憶體佈局。
int a[10], *p;
p = a; // 數組名退化為首元素地址 &a[0]
p = &a[0]; // 等價

p++:指針前移 sizeof(int) 字節,指向下一個元素。p + i:指向第 i 個元素 (相對於當前位置)。核心規則: 指針加減的步長 = sizeof(指向類型)。
| 下標法 | 指針法 | 等價關係 |
|---|---|---|
a[0] | *p / *a | a[i] == *(a+i) == *(p+i) == p[i] |
a[1] | *(p+1) / p[1] | |
a[2] | *(p+2) / p[2] | |
a[3] | *(p+3) / p[3] | |
a[4] | *(p+4) / p[4] |
// 1. 指針遍歷輸入
int a[10], *p = a;
for (int i=0; i<10; ++i) scanf("%d", p++); // p 走到尾部
// 2. 重置指針遍歷輸出
for (p = a; p < a+10; ++p) printf("%d ", *p);
注意: a++ 非法 (數組名是常量地址);p++ 合法。
int a[3] = {10,20,30}, *p = a;
printf("%d ", *p++); // ① 輸出 10,p 指向 a[1]
printf("%d ", *++p); // ② p 先進到 a[2],輸出 30
// (*p)++ // 指向元素值 +1,非指針 +1
*p++ ≡ *(p++):先取值,後指針+1。*++p ≡ *(++p):先指針+1,後取值。(*p)++:解引用後對元素值++。int a[3][4];
int (*p)[4] = a; // p 指向「含 4 個 int 的數組」 (即一行)
p = &a[2]; // 指向第 3 行

a[i][j] 地址 = a + i*4 + j (行優先存儲)*(*(a+i)+j) ≡ a[i][j]p[i][j] 同理,p 類型為 int (*)[4]char str[] = "I Love China!"; // 字符數組,存儲在棧/數據區,可修改
char *s = "I Love China!"; // 字符指針,指向只讀常量區,**不可修改內容**

所有 C 風格字符串以 '\0' 結尾,實際佔用長度 = 可見字符數 + 1。
// 遍歷字符串
char *p = s;
while (*p) { putchar(*p); ++p; }
// 字符串複製 (簡易版)
void strcpy(char *dest, const char *src) {
while ((*dest++ = *src++));
}
int a[] = {1,2,3,4,5};
int *p = a + 3;
printf("%d,%d,%d\n", *p, *(p+1), *p+3);
// 輸出:4, 5, 7
// 解析:p 指向 a[3]=4;*(p+1)=a[4]=5;*p+3 = 4+3=7
a[i] 編譯器直接轉為 *(a+i),指針與下標**完全等價**。int (*p)[COLS],括號不可省。const:const char *s = "...";。熟練掌握指針與數組的互轉,是寫出高效、無 Bug C 代碼的關鍵。