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

C 語言二維數組內存佈局:連續一維存儲與指針算術的本質

     編輯:程式設計疑難解答

現象代碼


int (*a)[2];      // 指向「含 2 個 int 的數組」的指針
int b[2][2];      // 2×2 二維數組
printf("size of first element of b is %d\n", sizeof(b[0][0])); // 4
a = b;
printf("size of first element of a is %d", sizeof(a[0][0]));   // 輸出 40(題目所述)

題目輸出 40 的原因:題目代碼可能存在筆誤或環境差異

標準 C 語言中:

  • sizeof(b[0][0]) = sizeof(int) = 4(32 位系統)
  • a = b 後,a 指向 b 首地址,類型為 int (*)[2]
  • a[0] 相當於 *(a+0),類型為 int[2](長度 2 的數組)
  • a[0][0] 相當於 *(*(a+0)+0),類型為 int
  • sizeof(a[0][0]) = sizeof(int) = 4,不會是 40

二維數組內存佈局鐵律


int arr[3][5];  // 3 行 5 列
內存連續佈局:[arr[0][0] arr[0][1] ... arr[0][4] arr[1][0] ... arr[2][4]]
總大小:3 * 5 * sizeof(int) = 15 * 4 = 60 字節

等價一維映射公式


// 訪問 arr[row][col]
// 等價於一維索引:row * COLS + col
// 地址計算:base + (row * COLS + col) * sizeof(int)
#define COLS 5
int *flat = (int*)arr;
flat[row * COLS + col] == arr[row][col];  // 恒真

指針類型與算術差異

表達式類型+1 移動字節數說明
a (int(*)[2])指向長度 2 數組的指針2 * sizeof(int) = 8跨過一整行
a[0] (int[2])長度 2 的數組(退化為 int*)sizeof(int) = 4指向行首元素
b (int[2][2])2×2 數組(退化為 int(*)[2])8同 a

驗證代碼(可直接運行)


#include 
int main() {
    int (*a)[2];
    int b[2][2] = {{1,2},{3,4}};
    printf("sizeof(b[0][0]) = %zu\n", sizeof(b[0][0])); // 4
    a = b;
    printf("sizeof(a[0][0]) = %zu\n", sizeof(a[0][0])); // 4
    printf("sizeof(a) = %zu\n", sizeof(a));             // 8 (指針大小)
    printf("sizeof(b) = %zu\n", sizeof(b));             // 16 (整個數組)
    return 0;
}

結論

二維數組在內存中是扁平化的一維連續塊,sizeof(a[0][0]) 永遠等於元素類型大小(sizeof(int))。題目所述 40 可能為 sizeof(a[0])(整行大小 8)誤讀,或環境非標準。掌握「行主序扁平化 + 指針步長 = 列數 × 元素大小」即可精準掌控多維數組內存。

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