- 项目概述:明确系统的目标和功能。
- 功能模块设计:将系统分解为各个功能模块。
- 数据结构设计:选择合适的数据结构来存储学生和课程信息。
- 核心代码实现:提供完整、带有详细注释的C语言代码。
- 系统编译与运行:说明如何编译和运行程序。
- 功能演示:展示程序运行流程。
- 总结与展望:对项目进行总结,并提出可以扩展的方向。
项目概述
项目名称:学生课程管理系统

开发语言:C语言
开发环境:任何支持C语言的编译器,如 GCC (Linux/macOS), MinGW/Dev-C++/Visual Studio (Windows)
项目目标: 设计并实现一个基于命令行的学生课程管理系统,该系统能够对学生信息和课程信息进行统一管理,支持学生信息的增、删、改、查,以及学生选课、退课、查询学生已选课程等功能,通过本课程设计,旨在加深对C语言结构体、指针、文件操作、排序算法等核心知识点的理解和应用。
功能模块设计
系统主要分为两大核心对象:学生 和 课程,系统功能围绕这两个对象展开。

| 模块 | 功能描述 |
|---|---|
| 学生管理 | |
| 添加学生 | 从键盘输入学生信息(学号、姓名),添加到系统中。 |
| 删除学生 | 根据学号删除指定学生及其所有选课记录。 |
| 修改学生信息 | 根据学号查找学生,并修改其姓名。 |
| 查询学生 | 根据学号或姓名查询并显示学生信息。 |
| 显示所有学生 | 以列表形式显示系统中所有学生的信息。 |
| 课程管理 | |
| 添加课程 | 从键盘输入课程信息(课程ID、课程名、学分),添加到系统中。 |
| 删除课程 | 根据课程ID删除指定课程。(注意:需要检查是否有学生已选该课程) |
| 修改课程信息 | 根据课程ID查找课程,并修改其名称或学分。 |
| 查询课程 | 根据课程ID或课程名查询并显示课程信息。 |
| 显示所有课程 | 以列表形式显示系统中所有课程的信息。 |
| 选课管理 | |
| 学生选课 | 为指定学号的学生选择一门课程(通过课程ID)。(注意:需检查学生和课程是否存在,以及是否已选) |
| 学生退课 | 为指定学号的学生退掉一门已选课程。 |
| 查询学生选课 | 显示指定学号的学生已选的所有课程信息,并计算总学分。 |
| 数据持久化 | |
| 保存数据 | 将当前所有学生和课程信息保存到文件中。 |
| 加载数据 | 从文件中加载之前保存的学生和课程信息。 |
| 系统管理 | |
| 退出系统 | 保存数据并退出程序。 |
数据结构设计
为了高效地管理数据,我们使用结构体来定义学生和课程,并使用动态数组来存储它们。
// 课程结构体
typedef struct {
int id; // 课程ID (唯一)
char name[50]; // 课程名称
float credit; // 学分
} Course;
// 学生结构体
typedef struct {
int id; // 学号 (唯一)
char name[50]; // 姓名
Course** courses; // 动态指针数组,指向该学生所选的课程
int course_count; // 已选课程数量
int course_capacity;// 动态数组的容量
} Student;
// 系统数据结构
typedef struct {
Student* students; // 动态指针数组,指向所有学生
int student_count; // 学生总数
int student_capacity;// 学生数组容量
Course* courses; // 动态数组,存储所有课程
int course_count; // 课程总数
int course_capacity;// 课程数组容量
} SystemData;
设计说明:
Student结构体中的courses是一个Course**(二级指针),因为它需要指向Course结构体的地址,我们使用动态数组来管理一个学生可以选多门课程的情况。SystemData结构体作为整个系统的核心数据容器,统一管理所有学生和课程列表,便于在函数间传递数据。- 使用
capacity和count是动态数组的经典用法,当数据量超过当前容量时,可以进行扩容,避免浪费内存或数组越界。
核心代码实现
下面是完整的 main.c 文件代码,代码包含了所有功能模块的实现,并附有详细的注释。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
// --- 常量定义 ---
#define INITIAL_CAPACITY 10
#define FILENAME "student_course_data.dat"
#define COURSE_FILENAME "courses.dat"
#define STUDENT_FILENAME "students.dat"
#define ENROLL_FILENAME "enrollments.dat"
// --- 数据结构定义 ---
typedef struct {
int id; // 课程ID (唯一)
char name[50]; // 课程名称
float credit; // 学分
} Course;
typedef struct {
int id; // 学号 (唯一)
char name[50]; // 姓名
Course** courses; // 动态指针数组,指向该学生所选的课程
int course_count; // 已选课程数量
int course_capacity;// 动态数组的容量
} Student;
typedef struct {
Student* students; // 动态指针数组,指向所有学生
int student_count; // 学生总数
int student_capacity;// 学生数组容量
Course* courses; // 动态数组,存储所有课程
int course_count; // 课程总数
int course_capacity;// 课程数组容量
} SystemData;
// --- 函数声明 ---
void init_system(SystemData* sys);
void free_system(SystemData* sys);
void show_menu();
void run_system(SystemData* sys);
void manage_students(SystemData* sys);
void manage_courses(SystemData* sys);
void manage_enrollments(SystemData* sys);
// 学生管理函数
void add_student(SystemData* sys);
void delete_student(SystemData* sys);
void modify_student(SystemData* sys);
void find_student(SystemData* sys);
void list_all_students(SystemData* sys);
// 课程管理函数
void add_course(SystemData* sys);
void delete_course(SystemData* sys);
void modify_course(SystemData* sys);
void find_course(SystemData* sys);
void list_all_courses(SystemData* sys);
// 选课管理函数
void enroll_course(SystemData* sys);
void drop_course(SystemData* sys);
void list_student_courses(SystemData* sys);
// 工具函数
void save_data(const SystemData* sys);
void load_data(SystemData* sys);
void expand_students(SystemData* sys);
void expand_courses(SystemData* sys);
void expand_student_courses(Student* stu);
Student* find_student_by_id(SystemData* sys, int id);
Course* find_course_by_id(SystemData* sys, int id);
void quick_sort_students(Student arr[], int low, int high);
int partition_students(Student arr[], int low, int high);
void quick_sort_courses(Course arr[], int low, int high);
int partition_courses(Course arr[], int low, int high);
void pause_and_clear();
// --- 主函数 ---
int main() {
SystemData sys;
init_system(&sys);
load_data(&sys);
run_system(&sys);
free_system(&sys);
return 0;
}
// --- 函数实现 ---
// 初始化系统数据
void init_system(SystemData* sys) {
sys->students = (Student*)malloc(INITIAL_CAPACITY * sizeof(Student));
sys->student_count = 0;
sys->student_capacity = INITIAL_CAPACITY;
sys->courses = (Course*)malloc(INITIAL_CAPACITY * sizeof(Course));
sys->course_count = 0;
sys->course_capacity = INITIAL_CAPACITY;
}
// 释放系统内存
void free_system(SystemData* sys) {
for (int i = 0; i < sys->student_count; i++) {
free(sys->students[i].courses);
}
free(sys->students);
free(sys->courses);
}
// 显示主菜单
void show_menu() {
printf("\n========== 学生课程管理系统 ==========\n");
printf(" 1. 学生管理\n");
printf(" 2. 课程管理\n");
printf(" 3. 选课管理\n");
printf(" 4. 保存数据\n");
printf(" 5. 加载数据\n");
printf(" 0. 退出系统\n");
printf("=====================================\n");
printf("请输入您的选择: ");
}
// 运行主循环
void run_system(SystemData* sys) {
int choice;
while (1) {
show_menu();
scanf("%d", &choice);
switch (choice) {
case 1: manage_students(sys); break;
case 2: manage_courses(sys); break;
case 3: manage_enrollments(sys); break;
case 4: save_data(sys); printf("数据已保存!\n"); pause_and_clear(); break;
case 5: load_data(sys); printf("数据已加载!\n"); pause_and_clear(); break;
case 0: save_data(sys); printf("感谢使用,再见!\n"); return;
default: printf("无效的输入,请重新选择!\n"); pause_and_clear();
}
}
}
// 学生管理菜单
void manage_students(SystemData* sys) {
int choice;
while (1) {
printf("\n--- 学生管理 ---\n");
printf("1. 添加学生 2. 删除学生 3. 修改学生\n");
printf("4. 查询学生 5. 显示所有 0. 返回主菜单\n");
printf("请选择: ");
scanf("%d", &choice);
switch (choice) {
case 1: add_student(sys); break;
case 2: delete_student(sys); break;
case 3: modify_student(sys); break;
case 4: find_student(sys); break;
case 5: list_all_students(sys); break;
case 0: return;
default: printf("无效输入!\n");
}
}
}
// 课程管理菜单
void manage_courses(SystemData* sys) {
int choice;
while (1) {
printf("\n--- 课程管理 ---\n");
printf("1. 添加课程 2. 删除课程 3. 修改课程\n");
printf("4. 查询课程 5. 显示所有 0. 返回主菜单\n");
printf("请选择: ");
scanf("%d", &choice);
switch (choice) {
case 1: add_course(sys); break;
case 2: delete_course(sys); break;
case 3: modify_course(sys); break;
case 4: find_course(sys); break;
case 5: list_all_courses(sys); break;
case 0: return;
default: printf("无效输入!\n");
}
}
}
// 选课管理菜单
void manage_enrollments(SystemData* sys) {
int choice;
while (1) {
printf("\n--- 选课管理 ---\n");
printf("1. 学生选课 2. 学生退课 3. 查询学生选课\n");
printf("0. 返回主菜单\n");
printf("请选择: ");
scanf("%d", &choice);
switch (choice) {
case 1: enroll_course(sys); break;
case 2: drop_course(sys); break;
case 3: list_student_courses(sys); break;
case 0: return;
default: printf("无效输入!\n");
}
}
}
// --- 学生管理函数实现 ---
void add_student(SystemData* sys) {
if (sys->student_count >= sys->student_capacity) {
expand_students(sys);
}
Student* new_stu = &sys->students[sys->student_count];
printf("请输入学号: ");
scanf("%d", &new_stu->id);
if (find_student_by_id(sys, new_stu->id)) {
printf("学号已存在,添加失败!\n");
pause_and_clear();
return;
}
printf("请输入姓名: ");
scanf("%s", new_stu->name);
new_stu->courses = (Course**)malloc(INITIAL_CAPACITY * sizeof(Course*));
new_stu->course_count = 0;
new_stu->course_capacity = INITIAL_CAPACITY;
sys->student_count++;
printf("学生添加成功!\n");
pause_and_clear();
}
void delete_student(SystemData* sys) {
int id;
printf("请输入要删除的学生学号: ");
scanf("%d", &id);
for (int i = 0; i < sys->student_count; i++) {
if (sys->students[i].id == id) {
// 释放该学生的课程数组
free(sys->students[i].courses);
// 将最后一个学生移到当前位置
sys->students[i] = sys->students[sys->student_count - 1];
sys->student_count--;
printf("学生删除成功!\n");
pause_and_clear();
return;
}
}
printf("未找到该学号的学生!\n");
pause_and_clear();
}
void modify_student(SystemData* sys) {
int id;
printf("请输入要修改的学生学号: ");
scanf("%d", &id);
Student* stu = find_student_by_id(sys, id);
if (stu) {
printf("请输入新的姓名: ");
scanf("%s", stu->name);
printf("学生信息修改成功!\n");
} else {
printf("未找到该学号的学生!\n");
}
pause_and_clear();
}
void find_student(SystemData* sys) {
int choice;
printf("1. 按学号查询 2. 按姓名查询\n");
printf("请选择: ");
scanf("%d", &choice);
if (choice == 1) {
int id;
printf("请输入学号: ");
scanf("%d", &id);
Student* stu = find_student_by_id(sys, id);
if (stu) {
printf("学号: %d, 姓名: %s\n", stu->id, stu->name);
} else {
printf("未找到该学号的学生!\n");
}
} else if (choice == 2) {
char name[50];
printf("请输入姓名: ");
scanf("%s", name);
bool found = false;
for (int i = 0; i < sys->student_count; i++) {
if (strcmp(sys->students[i].name, name) == 0) {
printf("学号: %d, 姓名: %s\n", sys->students[i].id, sys->students[i].name);
found = true;
}
}
if (!found) {
printf("未找到该姓名的学生!\n");
}
} else {
printf("无效选择!\n");
}
pause_and_clear();
}
void list_all_students(SystemData* sys) {
if (sys->student_count == 0) {
printf("系统中没有学生信息,\n");
pause_and_clear();
return;
}
printf("\n--- 所有学生信息 ---\n");
quick_sort_students(sys->students, 0, sys->student_count - 1);
for (int i = 0; i < sys->student_count; i++) {
printf("学号: %d, 姓名: %s\n", sys->students[i].id, sys->students[i].name);
}
pause_and_clear();
}
// --- 课程管理函数实现 ---
void add_course(SystemData* sys) {
if (sys->course_count >= sys->course_capacity) {
expand_courses(sys);
}
Course* new_course = &sys->courses[sys->course_count];
printf("请输入课程ID: ");
scanf("%d", &new_course->id);
if (find_course_by_id(sys, new_course->id)) {
printf("课程ID已存在,添加失败!\n");
pause_and_clear();
return;
}
printf("请输入课程名称: ");
scanf("%s", new_course->name);
printf("请输入学分: ");
scanf("%f", &new_course->credit);
sys->course_count++;
printf("课程添加成功!\n");
pause_and_clear();
}
void delete_course(SystemData* sys) {
int id;
printf("请输入要删除的课程ID: ");
scanf("%d", &id);
// 检查是否有学生选了这门课
for (int i = 0; i < sys->student_count; i++) {
for (int j = 0; j < sys->students[i].course_count; j++) {
if (sys->students[i].courses[j]->id == id) {
printf("错误: 有学生已选该课程,无法删除!\n");
pause_and_clear();
return;
}
}
}
// 如果没有学生选,则删除
for (int i = 0; i < sys->course_count; i++) {
if (sys->courses[i].id == id) {
sys->courses[i] = sys->courses[sys->course_count - 1];
sys->course_count--;
printf("课程删除成功!\n");
pause_and_clear();
return;
}
}
printf("未找到该ID的课程!\n");
pause_and_clear();
}
void modify_course(SystemData* sys) {
int id;
printf("请输入要修改的课程ID: ");
scanf("%d", &id);
Course* course = find_course_by_id(sys, id);
if (course) {
printf("请输入新的课程名称: ");
scanf("%s", course->name);
printf("请输入新的学分: ");
scanf("%f", &course->credit);
printf("课程信息修改成功!\n");
} else {
printf("未找到该ID的课程!\n");
}
pause_and_clear();
}
void find_course(SystemData* sys) {
int choice;
printf("1. 按课程ID查询 2. 按课程名查询\n");
printf("请选择: ");
scanf("%d", &choice);
if (choice == 1) {
int id;
printf("请输入课程ID: ");
scanf("%d", &id);
Course* course = find_course_by_id(sys, id);
if (course) {
printf("ID: %d, 名称: %s, 学分: %.1f\n", course->id, course->name, course->credit);
} else {
printf("未找到该ID的课程!\n");
}
} else if (choice == 2) {
char name[50];
printf("请输入课程名称: ");
scanf("%s", name);
bool found = false;
for (int i = 0; i < sys->course_count; i++) {
if (strcmp(sys->courses[i].name, name) == 0) {
printf("ID: %d, 名称: %s, 学分: %.1f\n", sys->courses[i].id, sys->courses[i].name, sys->courses[i].credit);
found = true;
}
}
if (!found) {
printf("未找到该名称的课程!\n");
}
} else {
printf("无效选择!\n");
}
pause_and_clear();
}
void list_all_courses(SystemData* sys) {
if (sys->course_count == 0) {
printf("系统中没有课程信息,\n");
pause_and_clear();
return;
}
printf("\n--- 所有课程信息 ---\n");
quick_sort_courses(sys->courses, 0, sys->course_count - 1);
for (int i = 0; i < sys->course_count; i++) {
printf("ID: %d, 名称: %s, 学分: %.1f\n", sys->courses[i].id, sys->courses[i].name, sys->courses[i].credit);
}
pause_and_clear();
}
// --- 选课管理函数实现 ---
void enroll_course(SystemData* sys) {
int student_id, course_id;
printf("请输入学生学号: ");
scanf("%d", &student_id);
Student* stu = find_student_by_id(sys, student_id);
if (!stu) {
printf("学生不存在!\n");
pause_and_clear();
return;
}
printf("请输入课程ID: ");
scanf("%d", &course_id);
Course* course = find_course_by_id(sys, course_id);
if (!course) {
printf("课程不存在!\n");
pause_and_clear();
return;
}
// 检查是否已选
for (int i = 0; i < stu->course_count; i++) {
if (stu->courses[i]->id == course_id) {
printf("该学生已选此课程!\n");
pause_and_clear();
return;
}
}
// 检查学生课程数组是否需要扩容
if (stu->course_count >= stu->course_capacity) {
expand_student_courses(stu);
}
stu->courses[stu->course_count++] = course;
printf("选课成功!\n");
pause_and_clear();
}
void drop_course(SystemData* sys) {
int student_id, course_id;
printf("请输入学生学号: ");
scanf("%d", &student_id);
Student* stu = find_student_by_id(sys, student_id);
if (!stu) {
printf("学生不存在!\n");
pause_and_clear();
return;
}
printf("请输入要退的课程ID: ");
scanf("%d", &course_id);
for (int i = 0; i < stu->course_count; i++) {
if (stu->courses[i]->id == course_id) {
// 将最后一门课移到当前位置
stu->courses[i] = stu->courses[stu->course_count - 1];
stu->course_count--;
printf("退课成功!\n");
pause_and_clear();
return;
}
}
printf("该学生未选此课程!\n");
pause_and_clear();
}
void list_student_courses(SystemData* sys) {
int student_id;
printf("请输入学生学号: ");
scanf("%d", &student_id);
Student* stu = find_student_by_id(sys, student_id);
if (!stu) {
printf("学生不存在!\n");
pause_and_clear();
return;
}
printf("\n--- 学号 %d (%s) 的选课信息 ---\n", stu->id, stu->name);
if (stu->course_count == 0) {
printf("该学生没有选任何课程,\n");
} else {
float total_credit = 0.0;
for (int i = 0; i < stu->course_count; i++) {
printf(" ID: %d, 名称: %s, 学分: %.1f\n", stu->courses[i]->id, stu->courses[i]->name, stu->courses[i]->credit);
total_credit += stu->courses[i]->credit;
}
printf("------------------------------------------------\n");
printf("总学分: %.1f\n", total_credit);
}
pause_and_clear();
}
// --- 数据持久化函数实现 ---
void save_data(const SystemData* sys) {
// 为了简化,这里将所有数据保存到一个文件中
// 实际项目中,可以考虑分开存储
FILE* fp = fopen(FILENAME, "wb");
if (!fp) {
perror("无法打开文件进行写入");
return;
}
// 写入学生数量
fwrite(&sys->student_count, sizeof(int), 1, fp);
// 写入所有学生信息
for (int i = 0; i < sys->student_count; i++) {
Student* s = &sys->students[i];
fwrite(s, sizeof(Student), 1, fp); // 写入学生基本信息
// 写入选课数量
fwrite(&s->course_count, sizeof(int), 1, fp);
// 这里不写入课程指针,而是写入课程ID,加载时再重建指针
for (int j = 0; j < s->course_count; j++) {
int id = s->courses[j]->id;
fwrite(&id, sizeof(int), 1, fp);
}
}
// 写入课程数量
fwrite(&sys->course_count, sizeof(int), 1, fp);
// 写入所有课程信息
fwrite(sys->courses, sizeof(Course), sys->course_count, fp);
fclose(fp);
}
void load_data(SystemData* sys) {
FILE* fp = fopen(FILENAME, "rb");
if (!fp) {
// 文件不存在是正常情况(第一次运行)
return;
}
// 读取学生
fread(&sys->student_count, sizeof(int), 1, fp);
if (sys->student_count > sys->student_capacity) {
sys->students = (Student*)realloc(sys->students, sys->student_count * sizeof(Student));
sys->student_capacity = sys->student_count;
}
for (int i = 0; i < sys->student_count; i++) {
Student* s = &sys->students[i];
fread(s, sizeof(Student), 1, fp); // 读取学生基本信息
s->courses = (Course**)malloc(INITIAL_CAPACITY * sizeof(Course*));
s->course_capacity = INITIAL_CAPACITY;
// 读取选课数量
fread(&s->course_count, sizeof(int), 1, fp);
if (s->course_count > s->course_capacity) {
s->courses = (Course**)realloc(s->courses, s->course_count * sizeof(Course*));
s->course_capacity = s->course_count;
}
s->course_count = 0; // 重置,下面重建指针时递增
// 读取选课ID并重建指针
int course_id;
for (int j = 0; j < (int)fread(&course_id, sizeof(int), 1, fp); j++) {
Course* c = find_course_by_id(sys, course_id);
if (c) {
s->courses[s->course_count++] = c;
}
}
}
// 读取课程
fread(&sys->course_count, sizeof(int), 1, fp);
if (sys->course_count > sys->course_capacity) {
sys->courses = (Course*)realloc(sys->courses, sys->course_count * sizeof(Course));
sys->course_capacity = sys->course_count;
}
fread(sys->courses, sizeof(Course), sys->course_count, fp);
fclose(fp);
}
// --- 工具函数实现 ---
void expand_students(SystemData* sys) {
sys->student_capacity *= 2;
sys->students = (Student*)realloc(sys->students, sys->student_capacity * sizeof(Student));
}
void expand_courses(SystemData* sys) {
sys->course_capacity *= 2;
sys->courses = (Course*)realloc(sys->courses, sys->course_capacity * sizeof(Course));
}
void expand_student_courses(Student* stu) {
stu->course_capacity *= 2;
stu->courses = (Course**)realloc(stu->courses, stu->course_capacity * sizeof(Course*));
}
Student* find_student_by_id(SystemData* sys, int id) {
for (int i = 0; i < sys->student_count; i++) {
if (sys->students[i].id == id) {
return &sys->students[i];
}
}
return NULL;
}
Course* find_course_by_id(SystemData* sys, int id) {
for (int i = 0; i < sys->course_count; i++) {
if (sys->courses[i].id == id) {
return &sys->courses[i];
}
}
return NULL;
}
// 快速排序实现 (用于学生列表)
void quick_sort_students(Student arr[], int low, int high) {
if (low < high) {
int pi = partition_students(arr, low, high);
quick_sort_students(arr, low, pi - 1);
quick_sort_students(arr, pi + 1, high);
}
}
int partition_students(Student arr[], int low, int high) {
Student pivot = arr[high];
int i = (low - 1);
for (int j = low; j <= high - 1; j++) {
if (arr[j].id < pivot.id) {
i++;
Student temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
Student temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
return (i + 1);
}
// 快速排序实现 (用于课程列表)
void quick_sort_courses(Course arr[], int low, int high) {
if (low < high) {
int pi = partition_courses(arr, low, high);
quick_sort_courses(arr, low, pi - 1);
quick_sort_courses(arr, pi + 1, high);
}
}
int partition_courses(Course arr[], int low, int high) {
Course pivot = arr[high];
int i = (low - 1);
for (int j = low; j <= high - 1; j++) {
if (arr[j].id < pivot.id) {
i++;
Course temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
Course temp = arr[i + 1];
arr[i + 1] = arr[high];
arr[high] = temp;
return (i + 1);
}
void pause_and_clear() {
printf("\n按回车键继续...");
getchar(); // 吸收上一个scanf留下的换行符
getchar(); // 等待用户输入回车
// system("cls"); // 如果是Windows系统,可以用这个清屏
// system("clear"); // 如果是Linux/macOS系统,可以用这个清屏
}
系统编译与运行
- 保存代码:将上面的完整代码复制并粘贴到一个文本文件中,命名为
main.c。 - 编译:
- 在 Linux/macOS (使用 GCC):
gcc main.c -o student_management_system
- 在 Windows (使用 MinGW/GCC):
打开命令提示符或 PowerShell,进入
main.c所在目录,然后运行:gcc main.c -o student_management_system.exe
- 在 Linux/macOS (使用 GCC):
- 运行:
- 在 Linux/macOS:
./student_management_system
- 在 Windows:
student_management_system.exe
- 在 Visual Studio:创建一个“控制台应用”项目,将代码粘贴到
main.c文件中,直接按F5运行。
- 在 Linux/macOS:
功能演示
-
启动程序:运行程序后,会显示主菜单。
(图片来源网络,侵删)========== 学生课程管理系统 ========== 1. 学生管理 2. 课程管理 3. 选课管理 4. 保存数据 5. 加载数据 0. 退出系统 ===================================== 请输入您的选择: -
添加学生:选择
1->1,输入学号1001和姓名张三。 -
添加课程:选择
2->1,输入课程IDCS101、名称C语言程序设计、学分0,再添加一门课程CS102数据结构0。 -
学生选课:选择
3->1,输入学生学号1001,课程IDCS101,选课成功。 -
查询学生选课:选择
3->3,输入学生学号1001,会显示张三的选课信息和总学分。 -
显示所有学生:选择
1->5,会按学号排序显示所有学生。 -
保存数据:选择
4,程序会将当前数据保存到student_course_data.dat文件中。 -
退出并重新运行:选择
0退出程序,然后再次运行程序,数据会被自动加载,你可以查询之前添加的学生和课程信息。
总结与展望
本项目成功实现了一个功能相对完整的学生课程管理系统,它涵盖了C语言的核心知识点,包括:
- 结构体:用于定义复杂的数据类型。
- 指针:特别是二级指针,用于构建复杂的数据关系(学生指向多门课程)。
- 动态内存分配:使用
malloc、realloc和free实现了动态数组的扩容和释放,使内存使用更高效。 - 文件I/O:实现了数据的持久化存储,可以将程序状态保存到磁盘并在下次启动时恢复。
- 算法:实现了快速排序算法,用于对列表进行排序显示。
- 模块化编程:将不同功能划分到不同函数中,代码结构清晰,易于维护和扩展。
可扩展的方向:
- 改进用户界面:使用
ncurses库(Linux)或 Windows API 来创建更美观的图形化用户界面。 - 增强数据验证:对用户输入进行更严格的检查(如学号、课程ID是否为数字,姓名不能为空等)。
- 优化数据存储:目前所有数据保存在一个二进制文件中,可以考虑使用数据库(如 SQLite)来存储数据,更易于管理和查询。
- 增加更多功能:
- 按学分范围查询学生。
- 统计每门课的选课人数。
- 成绩管理功能:为学生的每门课程添加成绩,并计算GPA。
- 用户权限管理:区分管理员和学生/教师角色。
- 代码重构:将
SystemData结构体封装成一个类(在C++中),利用面向对象的思想进一步优化代码结构,使其更具可扩展性和复用性。
这个项目为C语言学习者提供了一个非常好的实践平台,通过亲手实现它,可以极大地提升对C语言编程的综合理解能力。
