int a[4][4] = {
{1,2,3,4},
{50,60,70,80},
{900,1000,1100,1200},
{13000,14000,15000,16000}
};
int (*p1)[4] = a;
int (*p2)[4] = &a[0];
int *p3 = &a[0][0];
printf("%d, %d, %d, %d\n",
*(*(a+1)-1),
*(*(p1+3)-2)+1,
*(*(p2-1)+16)+2,
*(p3+sizeof(p1)-3)
);
環境:64 位 (指針 8 字節)。求輸出結果。
*(*(a+1)-1)a 類型 int (*)[4],指向第 0 行。a+1 → 第 1 行首地址 (即 &a[1][0]),類型仍 int (*)[4]。*(a+1) → 第 1 行首元素地址 &a[1][0],類型 int*,值為 50 的地址。*(a+1)-1 → 指針前移 1 個 int,指向 a[0][3] (值 4)。*(*(p1+3)-2)+1p1 同 a,p1+3 → 第 3 行首地址 (&a[3][0])。*(p1+3) → &a[3][0] (值 13000)。*(p1+3)-2 → 前移 2 個 int,指向 a[2][2] (值 1100)。*(*(p2-1)+16)+2p2 類型 int (*)[4],值 &a[0] (整個數組首地址)。p2-1 → 指針算術:p2 - 1*sizeof(int[4]),指向「第 -1 行」首地址,實際上是 a[3] 所在位置 (因數組連續,&a[0]-1 == &a[3] 的邊界外,但按題目邏輯視為繞行)。*(p2-1) → 該行首元素地址,即 &a[3][0] (13000)。+16 → 移動 16 個 int,恰好繞回 &a[3][0] (4行×4列=16)。*(p3+sizeof(p1)-3)sizeof(p1) = 8 (64 位指針大小)。p3 = &a[0][0] (一維視角)。p3 + 8 - 3 = p3 + 5 → 第 5 個元素 (0-based),即 a[1][1] (值 60)。4, 1101, 13002, 60
a[i][j] *(a[i] + j) // a[i] 退化為行首指針 *(*(a + i) + j) // a+i 為行指針,解引用得行首元素指針 *(p3 + i*COLS + j) // 一維指針 p3 指向 a[0][0]