雖然面向對象語言層出不窮,但 C 語言以極致效能與硬體親和力,長期佔據系統程式、嵌入式、高效能計算的王座。陣列與指標是 C 語言最基礎也最關鍵的兩大構件,深入理解二者互操作機制,是寫出高效、健壯代碼的前提。
type name[size] = {val_list};\0 結尾,字串字面常數自動補齊。char hello[] = "Hello"; 編譯器自動推導。陣列元素在記憶體中連續分佈,首元素位於最低位址,下標從 0 起算。元素位址計算公式:base + index * sizeof(type)。陣列名在大多數表達式中退化為指向首元素的指標(&arr[0]),但 sizeof(arr) 回傳整個陣列大小而非指標大小。
下標範圍 [0, N-1]。arr[N] 屬越界行為(C 標準未定義),嵌入式即時系統中可能導致崩潰。務必嚴守邊界,視程式設計為藝術而非僅是技術。
type *ptr; // 宣告
int *p = &var; // 初始化:取址運算子
int *p = NULL; // 空指標,標準定義於 stdio.h 等
指標類型決定指向物件的型別與運算語意。int *p, m, n; 僅 p 為指標,多指標需逐個加星號:int *p, *m, *n;。
| 運算式 | 等價形式 | 語意 |
|---|---|---|
*++p | *(++p) | 先遞增指標,再解參考 |
++*p | ++(*p) | 解參考後遞增所指值 |
*p++ | *(p++) | 解參考當前位置,再遞增指標 |
後綴 ++/-- 優先級高於前綴 *,務必牢記。
char hello[] = "Hello, world!";
char *p = hello;
do {
printf("%c", *p);
p++;
} while(*p); // 遇 \0 結束
str[9] // 下標法
*(pointer + 9) // 指標算術
p = &hello[3]; // 取元素位址
*&hello[3] // 取址後解參考,等價於 hello[3]
陣列名作參數實際傳遞首元素位址,函數簽名可寫 void func(int arr[]) 或 void func(int *ptr)。指標更靈活,可指向陣列中間任意位置。注意:printf(arr) 若編譯器將字串視為格式字串可能導致漏洞,建議統一使用 printf("%s", arr)。
'\n' 為字元,雙引號 "\n" 為字串。混用會導致邏輯錯誤,嵌入式系統後果嚴重。malloc、既有變數位址),否則解參考導致未定義行為。int *p = &char_var 違反嚴格別名規則,雖部分編譯器僅警告,但嚴重損害可移植性。malloc 回傳 NULL 時必須處理,避免空指標解參考。陣列提供結構化存儲,指標賦予靈活定址。二者看似相似,語意卻截然不同。精通互操作細節,方能在系統級開發中遊刃有餘,寫出既高效又安全的 C 代碼。