C 語言函式傳遞二維陣列時,參數宣告必須指定第二維度大小 (或使用指標陣列)。本文透過「學生成績統計」完整範例,示範 float (*score)[COLS] 參數模式,計算每位學生平均分與每門課程平均分。
#include
#define STUDENTS 6 // 列:學生數
#define COURSES 5 // 行:課程數
// 函式宣告:參數為「指向 COURSES 個 float 的陣列指標」
void input_scores(float (*score)[COURSES]);
void avg_per_student(float (*score)[COURSES]);
void avg_per_course(float (*score)[COURSES]);
int main() {
float scores[STUDENTS][COURSES]; // 6學生 x 5課程
input_scores(scores); // 陣列名自動退化為指向首行的指標
avg_per_course(scores); // 輸出每門課平均
avg_per_student(scores); // 輸出每學生平均
return 0;
}
// 輸入成績
void input_scores(float (*score)[COURSES]) {
for (int i = 0; i < STUDENTS; i++) {
printf("輸入第 %d 位學生 %d 門課成績: ", i+1, COURSES);
for (int j = 0; j < COURSES; j++) {
scanf("%f", &score[i][j]); // 等價 score[i][j]
}
}
}
// 計算並輸出每門課程平均分
void avg_per_course(float (*score)[COURSES]) {
printf("\n=== 各課程平均分 ===\n");
for (int j = 0; j < COURSES; j++) {
float sum = 0;
printf("課程 %d: ", j+1);
for (int i = 0; i < STUDENTS; i++) {
printf("%.1f ", score[i][j]);
sum += score[i][j];
}
printf("→ 平均: %.2f\n", sum / STUDENTS);
}
}
// 計算並輸出每位學生平均分
void avg_per_student(float (*score)[COURSES]) {
printf("\n=== 各學生平均分 ===\n");
for (int i = 0; i < STUDENTS; i++) {
float sum = 0;
for (int j = 0; j < COURSES; j++) {
sum += score[i][j];
}
printf("學生 %d: 平均 %.2f\n", i+1, sum / COURSES);
}
}
// 假設 COLS = 5
void func1(float score[][COLS]); // 最常用:省略第一維
void func2(float (*score)[COLS]); // 指標語法:score 是指向「COLS個float陣列」的指標
void func3(float score[ROWS][COLS]); // 完整寫法,ROWS 被忽略
核心規則: 編譯器需要知道每一列的大小 (即第二維度) 才能正確計算記憶體偏移 score[i][j] → *(score + i*COLS + j)。
scores[6][5] 在記憶體中連續佈局 (Row-major): Row 0: s[0][0] s[0][1] s[0][2] s[0][3] s[0][4] Row 1: s[1][0] s[1][1] s[1][2] s[1][3] s[1][4] ... score[i][j] 偏移 = i * COURSES + j
score[i][j] // 陣列語法
*(score[i] + j) // score[i] 是第 i 行首地址 (float*)
*(*(score + i) + j) // 完全指標形式
輸入第 1 位學生 5 門課成績: 85 90 78 92 88 輸入第 2 位學生 5 門課成績: 76 85 80 79 82 ... === 各課程平均分 === 課程 1: 85.0 76.0 ... → 平均: 80.50 課程 2: 90.0 85.0 ... → 平均: 87.20 ... === 各學生平均分 === 學生 1: 平均 86.60 學生 2: 平均 80.40 ...
| 錯誤代碼 | 問題 | 正確寫法 |
|---|---|---|
void func(float **score) | 雙重指標 ≠ 二維陣列,記憶體不連續 | void func(float (*score)[COLS]) |
void func(float score[][]) | 缺少第二維度大小 | void func(float score[][COLS]) |
| 動態配置二維陣列傳遞 | 指標陣列 float** 需配合索引陣列 | 用單維陣列 float* + 手動索引 [i*COLS+j] |
float* alloc_scores(int rows, int cols) {
return (float*)malloc(rows * cols * sizeof(float));
}
void free_scores(float* p) { free(p); }
// 存取宏
#define AT(score, i, j, cols) ((score)[(i)*(cols) + (j)])
int main() {
float* scores = alloc_scores(STUDENTS, COURSES);
AT(scores, 0, 0, COURSES) = 85.0f;
// ...
free_scores(scores);
return 0;
}
二維陣列指標參數 float (*score)[COLS] 是 C 語言處理矩陣/表格資料的標準模式。理解「第二維度決定步長」、「陣列名退化為行指標」、「指標算術等價性」三大核心,即能靈活處理各類矩陣運算、圖像處理、科學計算任務。