项目实践:学生成绩管理系统
项目背景
本系统是大一 C 语言课程设计的期末作品。要求在控制台环境下实现一个完整的学生成绩管理系统,涵盖数据的增删改查、排序筛选、文件持久化等功能。
项目的目标是综合运用 C 语言的核心知识:结构体、指针、链表、文件 I/O、字符串处理等。
功能设计
系统整体采用菜单驱动的交互方式,主要功能模块如下:
| 模块 | 功能描述 |
|---|---|
| 添加学生 | 录入学号、姓名、各科成绩 |
| 修改信息 | 按学号查找并修改学生数据 |
| 删除学生 | 按学号删除学生记录 |
| 查询成绩 | 支持按学号查询和按姓名模糊查询 |
| 成绩统计 | 计算总分、平均分、排名、最高/最低分 |
| 排序输出 | 按总分或学号排序,升序/降序可选 |
| 数据持久化 | 启动时从文件读取,退出时自动保存 |
数据结构
1 | typedef struct Student { |
使用单链表管理所有学生数据,相比固定数组更加灵活,支持动态增减。
关键技术点
1. 链表操作
核心是链表的增删改查。删除节点时需要正确处理前驱节点的指针重定向;插入节点时要维持链表的有序性。
2. 文件读写
使用 fopen / fread / fwrite 实现数据的二进制存储和读取。程序启动时自动加载数据文件,若文件不存在则创建空链表。
3. 排序算法
采用冒泡排序对链表进行排序,支持按总分或学号两种排序键,以及升序/降序两种模式。排序过程中只交换节点数据域,避免修改指针结构。
4. 输入校验
对学号做去重检查,对成绩做范围校验(0-100),对菜单选择做合法性判断,避免因非法输入导致程序异常。
遇到的问题与解决
问题一:删除操作导致链表断裂
最初忘记在删除时更新前驱节点的 next 指针。修复方式是引入
prev指针,在遍历时始终记录前一个节点。
问题二:文件读写时指针错位
写入文件时使用了文本模式而非二进制模式,导致部分数据截断。统一改为
"rb" / "wb"模式解决。
问题三:排序效率
冒泡排序在数据量大时效率较低。考虑到本系统面向课程展示,数据量有限,暂时保留;后续若有实际使用需求可升级为快速排序。
总结收获
这个项目让我真正体会到”做中学”的意义。课堂上以为已经掌握了的指针和链表,在实际编码时才发现理解其实很浅。通过一个个 bug 的调试,才逐渐建立起对这些概念的直觉。
最大的收获是:不要害怕报错。每一个段错误背后都有一个不合理的指针操作,去理解它、修复它,这就是进步。
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 Mistlane's Blog!
评论

