首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C >> C 語言基礎

C 語言基礎教程(四):指標指向二維陣列——記憶體佈局、指標算術與雙重指標等價形式

     編輯:C 語言基礎

二維陣列記憶體模型:陣列的陣列

宣告 int a[3][4] 可視為:3 個元素的陣列,每個元素是 4 個 int 的一維陣列。


a[0] → { a[0][0], a[0][1], a[0][2], a[0][3] }
a[1] → { a[1][0], a[1][1], a[1][2], a[1][3] }
a[2] → { a[2][0], a[2][1], a[2][2], a[2][3] }

位址計算規則 (假設基址 1000, sizeof(int)=2)

運算式型別位址值含義
aint (*)[4]1000第 0 列首址 (整個陣列首址)
a + 1int (*)[4]1008第 1 列首址 (跨越 4×2=8 bytes)
a + 2int (*)[4]1016第 2 列首址
a[0] / *aint *1000第 0 列首元素址
a[1] / *(a+1)int *1008第 1 列首元素址
a[i] + jint *1000 + (i×4 + j)×2第 i 列第 j 行元素址
&a[i][j]int *同上標準取址形式

元素存取四種等價形式


a[i][j]              /* 標準下標 */
*(a[i] + j)          /* a[i] 退化為 int*,加 j 後解參考 */
*(*(a + i) + j)      /* a 退化為 int(*)[4],a+i 指向第 i 列,解參考得 int*,再加 j 解參考 */
(*(a + i))[j]        /* 同上,利用下標運算子優先序 */

編譯器產生完全相同機器碼。

為何 a 與 *a 數值相同?

  • a:型別 int (*)[4],值為陣列首址 (1000)。
  • *a:解參考 a 得 a[0],型別 int [4],隨即退化為 int *,值仍為 1000 (第 0 列首元素址)。
  • 型別不同、數值相同:前者指向「4-int 陣列」,後者指向「int」。指標算術行為因此不同 (a+1 跳 8 bytes,*a+1 跳 2 bytes)。

實務建議

  • 傳遞二維陣列給函數:保留行大小 void f(int a[][4], int rows) 或 void f(int (*a)[4], int rows)。
  • 動態配置二維陣列:
    1. 連續記憶體:int *p = malloc(rows * cols * sizeof(int)); 存取 p[i*cols + j]。
    2. 指標陣列:int **p = malloc(rows * sizeof(int*)); for(i) p[i] = malloc(cols * sizeof(int)); 存取 p[i][j] (非連續)。
  • 避免三星級指標 int ***:極難維護,改用結構體封裝。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved