C 語言中 int (*p)[10] 和 int *p[10] 只差一對括號,卻代表完全不同的類型。本文從內存佈局、運算符優先級、實戰用法三個維度徹底釐清兩者區別,並給出判斷口訣。
| 概念 | 聲明語法 | 含義 | 類型 | sizeof(p) |
|---|---|---|---|---|
| 數組指針 | int (*p)[10] | 指向「包含 10 個 int 的數組」的指針 | int (*)[10] | 指針大小(4/8 字節) |
| 指針數組 | int *p[10] | 包含 10 個「指向 int 的指針」的數組 | int *[10] | 10 × 指針大小(40/80 字節) |
() 優先級 > [] > *(解引用)
int (*p)[10]:() 先結合 *p → p 是指針 → [10] 說明指向的類型是「長度 10 的數組」。int *p[10]:[] 先結合 p → p 是數組 → * 說明元素類型是指針。int m[10];
int *p1 = m; // 指向首元素,類型 int*
int (*p2)[10] = &m; // 指向整個數組,類型 int (*)[10]
printf("p1 = %p, p1+1 = %p\n", p1, p1+1); // 差 4 字節(sizeof(int))
printf("p2 = %p, p2+1 = %p\n", p2, p2+1); // 差 40 字節(sizeof(int[10]))
輸出示例:
p1 = 0x7ffe...fc, p1+1 = 0x7ffe...00 (差 4)
p2 = 0x7ffe...fc, p2+1 = 0x7ffe...28 (差 40)
void print_matrix(int (*mat)[4], int rows) { // 列數固定為 4
for (int i = 0; i < rows; i++)
for (int j = 0; j < 4; j++)
printf("%d ", mat[i][j]);
}
int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
print_matrix(a, 3); // a 退化為 int (*)[4]
char *argv[] = {"prog", "arg1", "arg2"}; // 指針數組
int *rows[3]; // 每行長度不同
rows[0] = malloc(10 * sizeof(int));
rows[1] = malloc(20 * sizeof(int));
rows[2] = malloc(5 * sizeof(int));
p。[] → 數組;無 → 繼續。* → 指針。int 等)。例:int (*p)[10]
p 是標識符。) 結束,無 []。* → p 是指針。[10] → 指向「長度 10 的數組」。int → 元素類型。int *p[10] 接收二維數組:實際傳入 int a[3][4] 類型為 int (*)[4],類型不匹配會警告/報錯。int *p[10] 寫成 int (*p)[10] 含義完全反轉。sizeof(p) 返回整個數組大小;對數組指針 sizeof(p) 返回指針大小,需用 sizeof(*p) 獲取所指數組大小。記住:數組指針是「指針」,指針數組是「數組」。括號位置決定了「誰修飾誰」。