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

C 語言多維陣列動態實作與位址計算原理

     編輯:關於C

從靜態定義到動態結構的通用多維陣列 ADT

C 語言原生多維陣列需在編譯期決定維度,且難以作為函數參數傳遞。本文實作一個通用的動態多維陣列抽象資料型別 (ADT),支援任意維度(最多 8 維)、執行期指定維界、元素存取與列印,核心在於**行優先**位址計算公式的預計算與泛型操作介面。

位址計算數學基礎

對維度為 dim、各維大小 bounds[0..dim-1] 的陣列,索引 (i0,i1,...,i_{dim-1}) 的線性位移:

offset = i0*B0 + i1*B1 + ... + i_{dim-2}*B_{dim-2} + i_{dim-1}
其中 Bk = bounds[k+1] * bounds[k+2] * ... * bounds[dim-1] (基數乘積)
B_{dim-1} = 1

預先計算 base_add[k] = Bk,存取時只需 offset = Σ index[k] * base_add[k],O(dim) 時間。

資料結構定義

typedef struct {
    int dim;            // 維度
    int *bounds;        // 各維大小 [dim]
    int *base_add;      // 基數乘積 [dim]
    int *data;          // 線性儲存空間
} Array;

核心 API

  • array_init(Array *a, int dim, ...):可變參數指定各維大小,配置記憶體並預計算 base_add。
  • array_set_value(Array *a, int val, ...) / array_get_value:可變參數指定索引,邊界檢查後存取。
  • array_print_line(Array *a):按行優先順序格式化列印。
  • array_destroy(Array *a):釋放三個動態陣列。

關鍵實作片段

int array_init(Array *a, int dim, ...) {
    if (dim < 1 || dim > 8) return -1;
    a->dim = dim;
    a->bounds = malloc(dim * sizeof(int));
    a->base_add = malloc(dim * sizeof(int));

    va_list ap; va_start(ap, dim);
    long total = 1;
    for (int i = 0; i < dim; i++) {
        a->bounds[i] = va_arg(ap, int);
        total *= a->bounds[i];
    }
    va_end(ap);

    a->data = malloc(total * sizeof(int));
    a->base_add[dim-1] = 1;
    for (int i = dim-2; i >= 0; i--)
        a->base_add[i] = a->base_add[i+1] * a->bounds[i+1];
    return 0;
}

int array_get_locate(Array *a, va_list ap) {
    int offset = 0;
    for (int i = 0; i < a->dim; i++) {
        int idx = va_arg(ap, int);
        if (idx < 0 || idx >= a->bounds[i]) return -1;
        offset += idx * a->base_add[i];
    }
    return offset;
}

使用範例:建立 4×6 二維陣列並填入 1..24

Array a;
array_init(&a, 2, 4, 6);
for (int i = 0; i < 4; i++)
    for (int j = 0; j < 6; j++)
        array_set_value(&a, i*6+j+1, i, j);
array_print_line(&a);   // 依記憶體順序列印
// 以矩陣形式列印
for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 6; j++)
        printf("%-7d", array_get_value(&a, i, j));
    puts("");
}
array_destroy(&a);

擴充方向

  • 支援任意元素型別:改用 void *data + size_t elem_size,操作函數傳入 memcpy。
  • 加入迭代器介面,支援 for_each 模式。
  • 實作切片、轉置、廣播等高階操作。

此實作展示 C 語言以結構體封裝資料與操作、可變參數處理多維索引、預計算優化存取效能的經典模式,可作為科學計算庫、影像處理框架的基礎組件。

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