陣列是 C 語言處理批量同質資料的基石。本文透過一個完整的「10 位學生成績統計」案例,示範陣列宣告、輸入驗證、統計計算、結果輸出的標準流程,並修正原始碼中的常見 Bug(拼寫錯誤、格式字串錯誤)。
#include <stdio.h>
#define STUDENT_COUNT 10
#define PASSING_SCORE 60
#define HIGH_SCORE 90
int main(void) {
int scores[STUDENT_COUNT];
int sum = 0;
int high_count = 0;
int pass_count = 0;
printf("=== 學生成績統計系統 ===\n");
printf("請輸入 %d 位學生的成績 (0-100):\n", STUDENT_COUNT);
for (int i = 0; i < STUDENT_COUNT; i++) {
int input;
while (1) {
printf("第 %2d 位: ", i + 1);
if (scanf("%d", &input) != 1) {
printf("輸入無效,請輸入整數。\n");
while (getchar() != '\n'); // 清空輸入緩衝區
continue;
}
if (input < 0 || input > 100) {
printf("成績範圍 0-100,請重新輸入。\n");
continue;
}
scores[i] = input;
break;
}
sum += scores[i];
if (scores[i] >= HIGH_SCORE) high_count++;
if (scores[i] >= PASSING_SCORE) pass_count++;
}
double average = (double)sum / STUDENT_COUNT;
double pass_rate = (double)pass_count / STUDENT_COUNT * 100.0;
printf("\n=== 統計結果 ===\n");
printf("總分: %d\n", sum);
printf("平均分: %.2f\n", average);
printf("及格人數 (≥%d): %d (%.1f%%)\n", PASSING_SCORE, pass_count, pass_rate);
printf("優秀人數 (≥%d): %d\n", HIGH_SCORE, high_count);
// 額外:分數分佈直方圖
printf("\n分數分佈:\n");
for (int bin = 100; bin >= 0; bin -= 10) {
int cnt = 0;
for (int i = 0; i < STUDENT_COUNT; i++) {
if (scores[i] >= bin && scores[i] < bin + 10) cnt++;
}
printf("%3d-%3d: ", bin, bin + 9);
for (int k = 0; k < cnt; k++) putchar('*');
printf(" (%d)\n", cnt);
}
return 0;
}
| 原始問題 | 錯誤碼 | 修正版 | 說明 |
|---|---|---|---|
| 陣列名拼寫錯誤 | scors[i] | scores[i] | C 語言區分大小寫,編譯會報「未宣告識別元」 |
| 平均分格式錯誤 | %f 對應 (sum*1.0)/10 | %.2f 對應 double average | 整數除法會截斷,必須轉型為 double |
| 無輸入驗證 | 直接 scanf | 迴圈驗證 + 緩衝區清理 | 防止非數字輸入導致無限迴圈 |
| 硬編碼魔術數字 | 10, 90, 60 | #define 常數 | 易維護、語意清晰 |
支援任意人數,使用 malloc/realloc:
int *scores = NULL;
int capacity = 0, count = 0;
int input;
printf("輸入成績 (負數結束):\n");
while (scanf("%d", &input) == 1 && input >= 0) {
if (count >= capacity) {
capacity = capacity ? capacity * 2 : 10;
int *tmp = realloc(scores, capacity * sizeof(int));
if (!tmp) { perror("記憶體不足"); free(scores); return 1; }
scores = tmp;
}
scores[count++] = input;
}
// ... 統計邏輯相同 ...
free(scores);
i < COUNT 而非 i <= COUNT。sum / count → (double)sum / count。memset 或賦值。scanf 回傳值未檢查:輸入「abc」會導致無限迴圈,務必檢查 == 1。scanf 和 getchar/fgets 時,需 while (getchar() != '\n'); 清理。看似簡單的陣列統計程式,實則包含輸入驗證、型別轉換、記憶體管理、錯誤處理等核心 C 語言功力。掌握「定義常數、驗證輸入、轉型計算、釋放資源」四步法,並善用編譯器警告(-Wall -Wextra)與靜態分析工具,能讓你寫出既正確又可維護的系統級程式碼。