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

C 語言二維數組作為函數參數:為何第一維可省略而第二維必須指定

     編輯:程式設計綜合問答

函數參數聲明 int Sum(int arr[][3]) 合法,但 int Sum(int arr[3][]) 非法。核心在於 C 語言數組在內存中的**線性佈局**與**編譯器地址計算**。

內存佈局:行優先

二維數組在內存中按行連續存儲:
arr[0][0], arr[0][1], arr[0][2], arr[1][0], arr[1][1], arr[1][2], ...

編譯器地址計算公式

訪問 arr[i][j] 時,編譯器生成代碼計算偏移:
offset = (i * COLS + j) * sizeof(int)

  • COLS (列數/第二維大小) **必須在編譯期已知**,否則無法計算跨行偏移。
  • ROWS (行數/第一維大小) **不參與地址計算**,只影響總大小檢查,故可省略。

形參本質:指向一維數組的指針

int Sum(int arr[][3]) 
// 等價於
int Sum(int (*arr)[3]) // arr 是指向「包含 3 個 int 的數組」的指針

編譯器知道每個「行」大小固定為 3 * sizeof(int),故 arr + i 正確跳過整行。

若允許第二維省略會發生什麼?

編譯器無法確定行大小,無法生成 arr[i][j] 的訪問代碼,導致編譯錯誤。

最佳實踐

  1. 函數參數聲明第二維大小:void func(int arr[][COLS]) 或 void func(int (*arr)[COLS])。
  2. 傳遞行數作為額外參數:void func(int arr[][3], int rows)。
  3. 動態分配二維數組時,改用「指針陣列」int **arr 或扁平一維數組 int *arr = malloc(rows * cols * sizeof(int)),自行計算索引 arr[i*cols + j]。

理解「行大小參與地址計算」是掌握 C 語言多維數組參數傳遞的關鍵。

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