功能完整的控制台學生成績管理系統,核心技術點:
main.c、students.h/c、store.h/cmain.c → 選單迴路、指令分派 students.h/c → 核心業務邏輯(鏈表操作、排序、查詢) store.h/c → 檔案讀寫持久化
// students.h
typedef struct Student {
unsigned long id; // 學號
char name[10]; // 姓名
float chinese, math, english;
double total; // 總分
float average; // 平均
struct Student* next; // 單向鏈表
} STU;
// 巨集:安全分配節點
#define ASK_STU(p) do { \
p = (STU*)malloc(sizeof(STU)); \
if (!p) { printf("malloc failed!\n"); exit(1); } \
} while(0)
// students.c
STU* select_sort(STU* head, char flag) {
STU *p, *q, *s, *t, *h = malloc(sizeof(STU));
h->next = head; p = h;
while (p->next && p->next->next) {
for (s = p, q = p->next; q->next; q = q->next) {
bool less = false;
switch (flag) {
case '1': less = q->next->id < s->next->id; break;
case '2': less = q->next->chinese < s->next->chinese; break;
case '3': less = q->next->math < s->next->math; break;
case '4': less = q->next->english < s->next->english; break;
case '5': less = q->next->average < s->next->average; break;
}
if (less) s = q;
}
if (s != p) { // 找到更小者,換到 p 後面
t = s->next;
s->next = t->next;
t->next = p->next;
p->next = t;
}
p = p->next;
}
head = h->next; free(h);
return head;
}
// store.c
#define FILE_NAME "students.dat"
void save_student(STU* head) {
FILE* fp = fopen(FILE_NAME, "w");
for (STU* p = head; p; p = p->next) {
fprintf(fp, "%lu %s %.1f %.1f %.1f %.1f %.1f\n",
p->id, p->name, p->chinese, p->math, p->english,
p->total, p->average);
}
fclose(fp);
printf("Saved.\n");
}
STU* init_student(STU* head) {
FILE* fp = fopen(FILE_NAME, "r");
if (!fp) return NULL; // 首次執行無檔案
STU *tail = NULL, *newNode;
while (1) {
ASK_STU(newNode);
int cnt = fscanf(fp, "%lu %s %f %f %f %lf %f",
&newNode->id, newNode->name,
&newNode->chinese, &newNode->math, &newNode->english,
&newNode->total, &newNode->average);
if (cnt != 7) { free(newNode); break; }
newNode->next = NULL;
if (!head) head = tail = newNode;
else { tail->next = newNode; tail = newNode; }
}
fclose(fp);
return head;
}
// main.c
int main() {
int cmd, initFlag = 0;
while (1) {
cmd = select_menu(); // 顯示選單、讀取鍵盤
handle_menu(cmd, &initFlag);
}
}
void handle_menu(int cmd, int* initFlag) {
static STU* head = NULL;
if (!*initFlag) { head = init_student(head); *initFlag = 1; }
switch (cmd) {
case '0': save_student(head); exit(0);
case '1': head = add_student(head); break;
case '2': head = del_student(head); break;
case '3': modify_student(head); break;
case '4': search_student(head); break;
case '5': head = display_student(head); break;
case '6': save_student(head); break;
}
}
**************************************************************
學生管理系統
1:添加學生信息 2:刪除學生信息
3:修改學生信息 4:查詢學生信息
5:查看學生信息 6:保存
0:退出
**************************************************************
請選擇: 1
請輸入學生學號: 2023001
請輸入學生名字: 張三
請輸入該學生英語成績: 85.5
請輸入該學生數學成績: 92.0
請輸入該學生語文成績: 78.0
添加成功,自動按學號排序。
學號 姓名 語文 數學 英文 平均分 總分
2023001 張三 78.0 92.0 85.5 85.2 255.5
| 現狀 | 改進建議 |
|---|---|
| 選擇排序 O(n²) | 改用合併排序 O(n log n) 或轉陣列 qsort |
| 固定姓名長度 10 | 動態分配或增大緩衝區,支援 Unicode |
| 文本檔案 | 二進制/ SQLite 提升大量資料效能 |
| 無索引查詢 O(n) | 學號雜湊表 / 姓名 Trie 樹加速 |
| 單檔案編譯 | CMake / Makefile 多檔案建置 |
| 無單元測試 | 加入 Unity / Check 測試框架 |
# GCC gcc main.c students.c store.c -o student_mgmt ./student_mgmt # MSVC (Developer Command Prompt) cl main.c students.c store.c /Fe:student_mgmt.exe student_mgmt.exe
本專案串聯了 C 語言核心技能:指標、結構體、動態記憶體、鏈表、檔案 I/O、排序、模組化設計。從零打造一個可執行的管理系統,是從「語法學習」邁向「工程思維」的關鍵一步。後續可延伸 C++ 重構(RAII、STL、類別封裝)、GUI 介面、資料庫整合等方向。