首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C++ 二維數組指針詳解:(*p)[2] 與 *(p[0]+1) 內存模型圖解

     編輯:程式設計疑難解答

代碼上下文

int a[3][4] = {
    {10, 20, 30, 40},
    {50, 60, 70, 80},
    {90, 100, 110, 120}
};
int (*p)[4] = a;  // p 指向 int[4] 類型,即 a 的首行地址

問題:解釋 (*p)[2] 與 *(p[0]+1) 為何分別輸出 30 和 20。

內存佈局圖解

a (首地址) → ┌────────────────────────────────────────┐
             │  a[0] (int[4])  │  a[1] (int[4])  │  a[2] (int[4])  │
             ├──────┬──────┬──────┬──────┼──────┬──────┬──────┬──────┤
             │  10  │  20  │  30  │  40  │  50  │  60  │  70  │  80  │ ...
             └──────┴──────┴──────┴──────┴──────┴──────┴──────┴──────┘
               ↑                          ↑
               p (int(*)[4])              p+1 (下一行首地址)

p[0] 等價於 *(p+0) → 取 p 指向的第一行 → 類型 int[4] → 退化為 int* 指向 10
p[0] + 1 → 指向 20
*(p[0] + 1) → 解引用 → 20

*p 解引用 p → 得到第一行 int[4](左值)
(*p)[2] → 對該數組下標 2 → 30

核心類型推導

p[0]+1 / *p+1*(p[0]+1)*p(*p)[2]
表達式類型值/含義
pint (*)[4]指向「含 4 個 int 的數組」的指針(行指針)
p[0] / *pint[4] → 退化 int*第一行首元素地址(&a[0][0])
int*第一行第二個元素地址(&a[0][1])
int第一行第二個元素值:20
int[4](左值)第一行整個數組對象
int第一行第 3 個元素值:30

關鍵結論

  • p[0] 是**第一行的首地址**(指向 10 的指針),**不是**指向指針的指針。
  • (*p)[2] 先解引用 p 得到「第一行數組」,再取下標 2。
  • *(p[0]+1) 先取第一行首地址,偏移 1 個 int,再解引用。
  • 二維數組在內存中是**連續存儲**的,行指針 p+1 跳過整行(4*sizeof(int) 字節)。

易混淆點辨析

int **q;       // 指向指針的指針(不連續,每行單獨 malloc)
int (*p)[4];   // 指向固定列數數組的指針(連續,棧上或整體 malloc)
// 切勿混淆!p 可以直接 p[0][2] 訪問,q 必須先分配行指針數組再分配每行。

理解「行指針」int (*)[N] 是掌握 C/C++ 二維數組指針的關鍵。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved