陣列與指標是 C 語言最核心也最易混淆的概念。許多教材僅說「陣列名是指標」,實則過度簡化。本文從 **宣告與定義**、**記憶體訪問機制**、**編譯器處理** 三個層面,釐清兩者本質差異。
int a[10];)。extern int a[];)。三種宣告情境:
extern int a[];)int a[10];) — 宣告的特例void f(int a[]);) — **唯一會退化為指標的宣告****賦值 x = y 中**:x 代表 **位址 (左值)**,y 代表 **內容 (右值)**。編譯期可知所有變數位址 (左值);執行期才知內容 (右值)。
a[i]:陣列名 a 在編譯期即為 **首元素位址 (常數左值)**。編譯器直接產生指令:位址 = a + i * sizeof(element),然後存取該位址。
→ **單次間接存取**。
*p 或 p[i]:指標 p 本身是一個 **變數**,有其儲存位址 (左值) 及儲存內容 (右值,即目標位址)。
步驟:
1. 讀取 p 的 **儲存位址** 取得 **目標位址** (右值)。
2. 用該目標位址存取資料。
→ **雙重間接存取**。

char a[100]; 定義 → extern char a[]; 或 extern char a[100]; 宣告:**合法** (皆表達「此處有陣列」)。char *p = "str"; 定義 → extern char *p; 宣告:**合法**。char a[100]; 定義 → extern char *a; 宣告:**錯誤**!宣告說「有個指標變數」,實際卻是陣列,會導致錯誤的雙重間接存取。char *p = "breadfruit";
p[0] = 'B'; → **未定義行為** (通常段錯)。char p[] = "breadfruit"; (陣列定義,內容複製到堆疊/資料段)。extern 宣告必須與定義的 **物件類型** 匹配 (陣列對陣列,指標對指標)。下一篇將討論函數調用中的陣列/指標行為、何時可互換、以及兩者的深層聯繫。