指標陣列是元素為指標的陣列。每個元素存放同一資料型別的地址。定義語法:
型別 *陣列名[長度];
int *ptrArray[10]; // 10 個指向 int 的指標
陣列名 ptrArray 是常數,指向首元素 ptrArray[0] 的地址。
二維字元陣列 char str[10][20] 強制每行固定寬度,浪費空間且難以交換行順序。指標陣列僅存放首地址,字串本體可放在唯讀區或動態配置區:
#include
const char *month_name(int n) { // 返回指向字串常數的指標
static const char *names[] = {
"Illegal month",
"January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"
};
return (n < 1 || n > 12) ? names[0] : names[n];
}
int main(void) {
for (int i = 0; i < 13; ++i)
printf("%2d: %s\n", i, month_name(i));
return 0;
}
關鍵點:
static 確保陣列生命週期覆蓋整個程式,避免返回區域變數地址const char* 防止意外修改字串常數(段錯誤)?: 簡化邊界檢查
void print_names(const char *names[], int n) {
for (int i = 0; i < n; ++i)
puts(names[i]);
}
int main() {
const char *fruits[] = {"Apple", "Banana", "Cherry"};
print_names(fruits, 3);
}
形參 const char *names[] 等價於 const char **names,退化為指向指標的指標。
#include
void sort_strings(char *names[], int n) {
for (int i = 0; i < n-1; ++i) {
int k = i;
for (int j = i+1; j < n; ++j)
if (strcmp(names[k], names[j]) > 0) k = j;
if (k != i) {
char *tmp = names[i];
names[i] = names[k];
names[k] = tmp; // 僅交換 4/8 bytes 指標
}
}
}
對比 strcpy 交換字串內容,指標交換效能提升數量級,尤其對長字串。
| 宣告 | 含義 | 元素型別 | 指標運算 p+1 增量 |
|---|---|---|---|
int *p[3] | 指標陣列(3 個指向 int 的指標) | int* | 指標大小 (4/8) |
int (*p)[3] | 指向「3 個 int 陣列」的指標 | int[3] | 3 * sizeof(int) (12/24) |
口訣:[] 優先級高於 *,int *p[3] 先結合 [3] → 陣列;加括號 int (*p)[3] 強制 *p 先結合 → 指標。
int matrix[3][4] = {{1,2,3,4}, {5,6,7,8}, {9,10,11,12}};
int (*rowPtr)[4] = matrix; // 指向第 0 行
for (int r = 0; r < 3; ++r) {
printf("Row %d: ", r);
for (int c = 0; c < 4; ++c)
printf("%d ", rowPtr[r][c]); // 或 *(*(rowPtr+r)+c)
puts("");
}
static 或動態配置const:導致未定義行為strcmp 參數順序:>0 表示第一參數較大NULL 結尾的指標陣列傳遞給期望哨兵的函數指標陣列是 C 語言處理「不等長序列」的標準利器。從月份名稱查詢到高效字串排序,核心思想都是間接層:操作指標而非資料本體。掌握 char *arr[] 與 char (*arr)[] 的語法區別,善用 const 與 static 管理生命週期,能寫出既高效又安全的字串處理代碼。