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

C 語言多維數組作為函數參數傳遞:指針語法完整指南與實戰代碼

     編輯:關於C語言

問題背景

需將二維數組 rain[5][12] 複製到 t1[5][12],要求函數使用指針語法而非下標語法完成拷貝,並能處理任意行列數。

函數原型與參數含義

void copy_ptr(const double (*src)[12], double (*dst)[12], int rows, int cols);
  • const double (*src)[12]:指向「含 12 個 double 的數組」的指針,即指向二維數組的一行(子數組)。const 保護源數據不被修改。
  • double (*dst)[12]:目標數組同類型指針。
  • rows, cols:運行時傳入的實際維度,解耦函數與固定列數 12。

指針算術解析

  • src + i:指向第 i 行(偏移 i * 12 * sizeof(double) 字節)。
  • *(src + i):解引用得到第 i 行的首元素地址(類型 double *)。
  • *(*(src + i) + j):等價於 src[i][j],訪問第 i 行第 j 列元素。

完整實現代碼

#include 

void copy_ptr(const double (*src)[12], double (*dst)[12], int rows, int cols) {
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j) {
            *(*(dst + i) + j) = *(*(src + i) + j);
        }
    }
}

int main(void) {
    const double rain[5][12] = {
        {4.3,4.3,4.3,3.0,2.0,1.2,0.2,0.2,0.4,2.4,3.5,6.6},
        {8.5,8.2,1.2,1.6,2.4,0.0,5.2,0.9,0.3,0.9,1.4,7.3},
        {9.1,8.5,6.7,4.3,2.1,0.8,0.2,0.2,1.1,2.3,6.1,8.4},
        {7.2,9.9,8.4,3.3,1.2,0.8,0.4,0.0,0.6,1.7,4.3,6.2},
        {7.6,5.6,3.8,2.8,3.8,0.2,0.0,0.0,0.0,1.3,2.6,5.2}
    };
    double t1[5][12] = {0};

    copy_ptr(rain, t1, 5, 12);

    // 驗證輸出
    for (int i = 0; i < 5; ++i) {
        for (int j = 0; j < 12; ++j)
            printf("%.1f%c", t1[i][j], j==11?'\n':' ');
    }
    return 0;
}

關鍵理解:多維數組的指針鏈本質

二維數組在內存中是連續一維數組的集合。類型系統視角:

  • double [5][12] → 5 個 double [12] 的數組
  • 傳參時退化為 double (*)[12](指向首個 double [12] 的指針)
  • 每次解引用 * 降低一維:*p 得到 double [12],再退化為 double *

這形成一條指針鏈:double (*)[12] → double * → double,每層步長不同,編譯器根據類型自動計算偏移。

進階:通用列數的 VLA 寫法 (C99)

void copy_vla(int rows, int cols, const double src[rows][cols], double dst[rows][cols]) {
    for (int i = 0; i < rows; ++i)
        for (int j = 0; j < cols; ++j)
            dst[i][j] = src[i][j];  // 下標語法更清晰,編譯器同樣生成指針算術
}

VLA 允許運行時確定維度,調用時無需固定列數,更靈活。

常見錯誤避坑

錯誤寫法問題正確寫法
void f(double **a)指針數組 ≠ 二維數組,內存佈局不同void f(double (*a)[COLS]) 或 VLA
void f(double a[][])缺少列數,編譯器無法計算行步長必須指定列數或用 VLA
忽略 const源數組可被意外修改加 const 保護只讀參數
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved