| 特性 | int a[10][20] (真二維陣列) | int *b[10] (指標陣列) |
|---|---|---|
| 記憶體分配 | 連續分配 200 個 int (10×20) | 僅分配 10 個指標 (未初始化) |
| 儲存模型 | 單一連續區塊,行優先 (Row-major) | 指標陣列 + 各指標指向獨立分配的區塊 |
| 存取方式 | a[i][j] 編譯器自動計算位移 | b[i][j] 需先解參考 b[i] 再索引 |
| 初始化 | 定義即完成,可靜態初始化 | 必須顯式初始化每個指標 (malloc/靜態陣列) |
| 行長度彈性 | 固定,所有行長度相同 | 每行長度可不同 (鋸齒陣列) |
| 傳遞給函數 | 退化為 int (*)[20] (指向 20 元素陣列的指標) | 退化為 int ** (指標的指標) |
a[10][20]起始位址: a a[0][0] a[0][1] ... a[0][19] a[1][0] a[1][1] ... a[9][19] |<------ 連續 200 * sizeof(int) 位元組 ------>|
位移公式:offset = (i * 20 + j) * sizeof(int)。編譯時期已知列數 (20),故可直接計算。
b[10]b (指標陣列) 堆疊/資料區上的 10 個指標 +-----+-----+-----+-----+-----+ | b[0]| b[1]| b[2]| ... | b[9]| +-----+-----+-----+-----+-----+ | | | | v v v v [20 ints] [20 ints] ... [20 ints] (各自獨立 malloc,位址不連續)
若每行 malloc(20 * sizeof(int)),總記憶體 = 10 * sizeof(int*) + 10 * 20 * sizeof(int)。
[c]
#include <stdio.h>
#include <stdlib.h>
int main() {
// 真二維陣列
int a[2][3] = {{1,2,3}, {4,5,6}};
printf("a[1][2] = %d\n", a[1][2]); // 6
printf("a addr: %p, a+1: %p (diff=%zu)\n", a, a+1, (char*)(a+1)-(char*)a); // 差 3*sizeof(int)
// 指標陣列
int *b[2];
b[0] = (int[]) {1,2,3}; // C99 複合字面量
b[1] = (int[]) {4,5,6};
printf("b[1][2] = %d\n", b[1][2]); // 6
printf("b addr: %p, b+1: %p (diff=%zu)\n", b, b+1, (char*)(b+1)-(char*)b); // 差 sizeof(int*)
// 動態分配鋸齒陣列
int *c[3];
c[0] = malloc(2 * sizeof(int)); c[0][0]=1; c[0][1]=2;
c[1] = malloc(4 * sizeof(int)); c[1][0]=3; c[1][1]=4; c[1][2]=5; c[1][3]=6;
c[2] = malloc(1 * sizeof(int)); c[2][0]=7;
// ... 使用後需逐行 free
return 0;
}
std::vector<std::vector<T>> 或單一 std::vector<T> + 手動索引;C 可封裝結構體 struct Matrix { int rows, cols; int *data; } 統一管理。