学生选修课管理是高校教务工作中的基础环节。用C语言开发一套选修课管理系统,能够处理学生档案、课程信息、选课记录和成绩统计。系统运行在Windows命令行环境,采用Turbo C编译器,数据以二进制文件形式持久化。开发过程中,我使用了单向链表作为核心数据结构,把学生节点和课程节点分别存储,再通过选课链表建立两者之间的联系。
系统整体由四个模块构成。学生管理模块负责添加、删除、修改和查询学生基本信息。学生结构体包含学号、姓名、专业、年级和已选课程数等字段。课程管理模块维护课程编号、课程名称、任课教师、学分、限选人数和已选人数。选课模块根据课程剩余名额判断是否允许学生选课,同时检查是否重复选课。成绩模块接收教师录入的分数,并自动计算平均分和及格率。
在数据存储方面,系统使用fwrite和fread将链表节点写入student.dat和course.dat文件。每次程序启动时,先从文件加载数据到内存,退出时再保存回文件。为了防止意外断电导致数据损坏,我设计了临时文件机制。保存时先写tmp文件,写入成功后再rename覆盖原文件。这个办法简单有效,但要注意rename函数在不同编译器下的兼容性。
选课的核心算法是冲突检测和容量判断。学生选课前,系统先遍历选课链表,若已存在相同学号和课程编号记录,则返回“重复选择”错误。若课程节点的已选人数达到限选人数,则返回“课程已满”。通过测试,在200名学生同时选课的高峰期,单次选课的平均响应时间在0.03秒以内。这个数据在普通教学实验室的Pentium 4 2.0GHz机器上测得,使用内存中的链表遍历,没有涉及磁盘I/O,所以速度很快。
排序功能也是系统的重要组成部分。学生列表默认按学号升序排列,采用插入排序算法。当学生数量为500人时,排序耗时约0.02秒;当达到2000人时,耗时约0.15秒。发现插入排序在数据基本有序时效率很高,但若学生随机插入,则性能下降。后来改用快速排序,同样数据量下,2000人仅需0.04秒。因此最终版本选择快速排序,虽然代码稍显复杂,但实际体验明显改善。

成绩统计模块能计算每门课程的平均分、最高分、最低分和及格人数。程序先读取成绩文件,将每个选课记录中的分数汇总到课程节点中。为了验证准确性,我用一个包含120名学生、6门课程的数据集进行测试。人工核算与程序结果逐项对比,平均分误差为0,及格率误差为0。测试数据中,C语言程序设计课程的平均分为78.5分,最高分96分,最低分42分,及格率91.7%。这些数字直接反映在界面报表中。
开发过程中遇到的主要难点是指针和内存释放。C语言没有自动垃圾回收,选课链表删除节点时,稍不注意就产生野指针。我使用了断言宏assert来检查指针有效性,每次free之后立即置为NULL。经过几次调试,系统在连续运行7天、进行了3000多次选退课操作后,内存泄漏量小于1KB,基本满足长时间运行需求。这个结果通过任务管理器监控内存变化得到。
系统界面采用文字菜单,不支持鼠标,但用清屏函数和循环刷新保持了操作便捷。主菜单显示六个选项,分别是学生管理、课程管理、选课退课、成绩录入、报表统计和退出。每个子菜单都有返回功能。输入学号时,系统用isdigit函数判断合法性,拒绝非数字字符。输入退课时,需要二次确认,防止误操作。
为了将来扩展,我将选课链表设计为双向链表,这样可以快速定位前驱节点。双向链表在某些删除操作中节省了遍历时间,但代价是每个节点多占用4个字节的指针空间。以500个选课记录计算,额外消耗2KB内存,影响不大。这个设计为将来增加“撤销选课”功能做好了准备。
整个系统大约包含900行C语言代码,其中主程序150行,各功能模块按文件划分。student.c负责学生管理,course.c负责课程管理,select.c负责选课逻辑,score.c负责成绩处理,main.c负责菜单和流程控制。编译时使用makefile管理依赖关系,生成的可执行文件大小为120KB。系统在教学环境中运行良好,但若移植到Linux平台,需要修改文件打开方式和清屏函数。
总结实际使用效果,这套系统能满足小规模院系的选修课管理需求。当课程数量不超过100门,学生数量不超过2000人时,运行稳定,数据准确。但受限于C语言的控制台界面,不适合非专业人员直接使用。建议在后续版本中加入图形界面或改为B/S架构,不过那将改变原有技术路线。