1.问题概述

随着学校的规模不断扩大,学生数量急剧增加,有关学生的各种信息量也成倍增长。面对庞大的信息量需要有学生管理系统来提高学生管理工作的效率。通过这样的系统可以做到信息的规范管理、科学统计和快速查询、修改、增加、删除等,从而减少管理方面的工作量。需要设计一个学生综合测评的信息及成绩的管理系统,以解决传统纸质信息统计的不易修改,储存及放置等诸多不便及弊端。来简化学校的办公,节约时间及人力。

2.系统需求分析

在学生信息的日常管理中,经常需要对学生相关信息进行处理,采用传统的手工记录,查询方式,显然有很多不便,如多次的增、删、改可能使信息变得混乱,为今后的信息提取带来很多麻烦。为了解决这一问题,可采用现代化的手段—计算机进行系统的管理。这样可大大提高管理的质量和效率,并且使学生的信息管理也从手工操作中解脱出来,减少纸制材料的数量,对日常信息的查询、方便、快捷。因此,基于这些方面的考虑,决定开发本系统。

3.系统概要设计

3.1系统主要功能

系统的主要功能是实现学生基本的信息及成绩的录入和管理
主要包括:
(1)学生信息的添加
(2)学生信息的修改
(3)学生信息的删除
(4)学生信息的插入
(5)学生成绩按平均成绩排名
(6)学生成绩按某一门课排序
(7)统计某一门课不及格人数

3.2系统的总体结构

(1)程序主界面的设计

图3.2.1系统主界面结构图

(2)学生信息处理子界面设计

图3.2.2系统子界面结构图1

图3.2.3系统子界面结构图2

(3)学生信息处理分析

①添加学生学号、姓名、数据结构、大学英语
②选择需要修改的类别进行修改
③选择需要删除的学生学号进行删除
④选择需要插入的位置(插入到该位置前)进行学生信息插入

(4)学生数据处理分析

①按照数据结构、大学英语两门门课成绩的平均成绩对学生信息排序
②按照数据结构、大学英语中某一门课成绩对学生信息排序
③选择需要统计不及格人数科目,统计该门课的不及格人数
④按照学号、姓名、数据结构成绩、大学英语成绩、平均成绩将学生信息输出至屏幕上
⑤根据学号查找相关学生信息

3.3数据结构的设计

学生信息数据结构类型如下:

4.系统详细设计

①根据系统总体结构对问题进行的模块划分,对总的问题可划分为:学生信息处理、学生数据处理、学生信息显示三大模块
②在主函数中创建了StudList类的对象list,先调用了CreateList()函数创建一个空的表,再调用了menu(&list)函数显示主菜单,主菜单中调用了学生信息处理和学生数据处理菜单。


③学生信息处理调用Add()、Insert()、Delete()、Alter()来显示子菜单,同时实现添加,插入,删除,修改功能。
④学生数据处理调用了sortAver()、sort()、CountNode()、Seek()来显示子菜单,同时实现按平均成绩排序、按某一课成绩排序、统计某一课成绩不及格人数功能、按学号查找学生相关信息。

4.1主菜单 menu(&list)

(1)系统流程

①该函数主要用来显示主菜单的内容以及进入子菜单实现功能,该函数实现过程中首先定义了一个变量a,这是用户选择进入那个模块的选项。
②首先判断a的值,如果为2、3、4、5则进入学生信息处理。为2调用Add()进行添加操作;为3调用Alter()进行修改操作;为4调用Delete()进行删除操作;为5调用Insert()进行插入操作。
③如果为1、6、7、8、9则进入学生数据处理。为1调用Display()显示所有学生信息;为6调用sortAver()按平均成绩排名;为7调用sort()按某一课成绩排序;为8调用CountNode()统计某一课成绩不及格人数;为9调用Seek()按学号查找学生相关信息。

(2)代码实现


4.2子菜单

4.2.1学生信息处理(Add()、Insert()、Delete()、Alter())

(1)Add()函数

①用来添加学生信息,该函数实现过程中首先定义了三个指针p、t。p用来读取数据,t用于判断是否输入重复学号。首先使用if判断头结点是否为空,若为空,则为申请一个新的空间。
之后将头指针赋给t,再为p申请新的空间。
要求用户输入学生学号并储存在 p->num中。使用while判断输入的学号是否重复,重复则输出”已存在该学号!”并结束Add()程序。
若输入学号不重复,则要求用户输入学生姓名、数据结构成绩、大学英语成绩、大学物理成绩。并调用averGrade(p)函数进行三门成绩平均分的计算,计算结果存放在链表的average中。
最后将p的next指向head,head变为p。
②代码实现

(2)Insert()函数

①用来插入学生信息,该函数实现过程中首先定义了两个变量i和len,根据用户输入的位置赋给i,然后调用getlen()函数计算当前链表长度。用while判断当前表是否为空。若为空,则输出”当前表为空!”并结束Insert()程序。
用if判断用户输入位置是否符合要求,若不符合要求,则输出”该位置不存在”并结束Insert()程序。
在表不为空并且输入位置正确情况下,将头指针赋给定义的两个指针cur和pr。进行i—,使插入位置在选择的位置之前。
利用while使cur指向需要插入数据的地方,pr指向cur的前驱。
将头指针赋给定义指针的变量t。
将输入的学号赋给定义的指针变量newNode,利用while判断,插入的学号是否已经存在,若已经存在,则输出”已存在该学号!” 并结束Insert()程序。
若输入的学号并未重复,则要求用户输入学生姓名、数据结构成绩、大学物理成绩。分别赋给newNode->name、newNode->DataStructur、newNode->English中,然后调用averGrade(newNode)函数计算两门科目成绩平均值。
最后,将newNode插入到pr和cur中间。
②代码实现

(3)Delete()函数

①用来删除学生信息,该函数实现过程中首先定义两个指针变量cur和pr,将头结点赋给两个指针变量。定义一个变量n,将输入的学号赋给n。
用while进行循环判断,若此次没有找到对应学号,则cur指向下一个结点,pr指向cur的前驱并结束Delete()程序。若找到对应的学号,判断是否是头结点或尾结点。若为头几点,则令头结点为头节点的后继结点;若为尾结点,则pr为尾结点,令pr的next为cur->next并结束Delete()程序。
若循环结束还未找到对应学号,则输出”没有查到要删除的学号”并结束Delete()程序。
②代码实现

(4)Alter()函数

①用来修改学生信息,该函数实现过程中首先定义两个变量a、n,将输入的学号赋给n,用if判断学号是否存在,若不存在则输出”不存在该学号!”并结束Alter()程序。
用while遍历数据,寻找需要修改数据对应的学号。找到后,利用switch语句判断具体需要修改的数据并进行修改。若输入除1、2、3以外数据,则直接退出修改。
②代码实现

4.2.2学生数据处理(sortAver()、sort()、CountNode()、Display()、Seek())

(1)sortAver()函数

①用来按平均成绩排序学生数据,该函数实现过程中首先定义三个变量len、inlen、rank,len和inlen用来解决排序问题,rank为名次。
利用两层while循环对原数据进行冒泡排序,最核心的交换调用swapNode(cur, cur->next)实现。
之后利用while进行输出即可,其中还需用if来避免平均成绩重复的情况出现。
②代码实现

(2)sort()函数

①用来按某一门课程成绩排序学生数据,该函数实现过程中首先定义一个变量m,将输入的值赋给m进行判断具体按照哪一门课排序,若输入1,则调用sortD()按数据结构成绩排序;若输入2,则调用sortE()按大学英语成绩排序。两者排序实现方式相同,均用两层while进行冒泡排序。
②代码实现

(3)CountNode()函数

①用来计算某一门课不及格学生人数,该函数实现过程中首先定义一个变量m,将输入的值赋给m进行判断统计哪一门科目不及格人数,若输入1,则调用CountNotD()函数统计数据结构不及格人数;若输入2,则调用CountNotE()函数统计大学英语不及格人数。
两者实现统计方式相同,均通过while遍历结点,输出小于60的学生并输出统计的人数。
②代码实现


(4)Display()函数

①用来显示所有学生数据,该函数实现过程中首先定义一个指针变量cur,将头结点赋给cur,再定义一个len变量,通过调用getlen()函数将学生人数赋给len变量,并且在屏幕输出。
用while遍历输出学生数据。
②代码实现

(5)Seek()函数

①用来显示所有学生数据,该函数实现过程中首先定义两个指针变量cur和pr,将头节点赋给cur和pr,通过一个while循环,遍历节点,pr跟着cur,若查找到了对应学号,输出相关信息,若查找不到输出”没有查到要查找的学号”

②代码实现

5.系统的测试及调试

系统的测试及调试是为了发现程序中错误而执行程序的过程。

5.1运行过程

(1)运行该程序,进入主界面,出现选择菜单


输入2、3、4、5可进入学生信息处理界面,输入1、6、7、8、9可进入学生数据处理界面

(2)进行学生信息处理

选择2进行信息添加


选择3进行信息修改

选择4进行信息删除

选择5进行信息插入

(3)进行学生数据处理

选择6按平均成绩排名

选择7按某一课成绩排序

选择8统计某一课成绩不及格人数

选择9统计某一课成绩不及格人数

5.2系统调试过程中遇到的问题

(1)录入学生信息后能够写进文件,但是只能查询时只能查询到第一个人的信息
错误原因:录入信息后储存后。无法知道信息的条数。读取的时候只读取了第一条。
解决方案:在信息录入的时候设置一个变量来记录学生信息录入的条数。并且将条数写进文件中,读取的时候将它先读出来,再读取学生信息。

(2)录入学生信息后再次读取,学生学号变为乱码。
错误原因:录入完信息后储存了一个记录学生信息条数的变量。这个数储存的时候储存在了文件的第一个位置。而学生信息所在的结构体则在后面,所以读取的时候出错。
解决方法:将结构体的第一个用来储存记录学生信息变化的数据。信息录入则从第二个开始录入。

(3)第二次录入学生信息与第一次录入学生信息的时候变量的设置第20页问题。
错误原因:在第一次录入时读不到设置的变量而第二次需要读取设置的变量。
解决方案:在打开文件时增加一个判断,文件是否为空,若是空则便是第一次写入学生信息,则设置变量为0。若不为空,则读取变量,并继续进行累加。

其他错误与此类似,便不一一举例。

6.用户手册

(1)本系统执行文件为Student Information Management System.cpp
(2)进入系统界面后,在主菜单的中,选择相应的操作前的数字,出现提示界面。根据提示输入相关信息或得到预期结果
(3)在输入信息时:学号为整型型
姓名 1-5个汉字或1-10个英文字母
考试成绩都为0-100的数字

7.总结

在三天的苦力后,我的学生信息综合管理系统项目课程设计终于完工了,虽然系统还不够完善,但是已经具备了一个信息管理系统的基本功能。一周的课程设计,虽然很忙碌,但我感觉收获很多,不仅仅在知识和技术上,而且我也懂得了很多人生哲理,懂得怎么样去制定计划,怎么样去实现这个计划。曾经有过放弃本系统的念头,曾经有过敷衍了事的想法。但是每一次技术突破的喜悦,都让我坚定了胜利的信念。通过这次程序设计,让我更好的了解 C++,对系统的编译有了更深刻的认识。
在测试和调试方面,曾经天真的一位编程才是最浪费时间的,在这次实践中,让我更加清楚的认识到,软件测试和调试在整个工作中所占的比例。也让我更加相信调试是软件开发中最艰巨的脑力劳动。本次课程设计中出现了许多隐藏的错误,令我收获不少。但我相信也一定会有很多未发现的问题,特别是在以后的系统扩展中,种些问题会更明显,但我相信问题的出现就是需要我们去解决。
通过这次课程设计我通彻的体会到了一个问题:在做实验前一定要将课本上的知识吃透,因为这是实验的基础,否则,这将使你做实验的难度加大,浪费做实验的宝贵时间。比如说文件的使用,因为没有将文件的使用学习贯彻,所以导致在调试的时候出现各种错误。在做实验的时候才去摸索,这将使我极大地浪费时间。
在这次课程设计中我学到了很多很多。受益匪浅。总体来说,这次C语言程序设计实验还是比较成功的,虽然最终程序还存在一些不足,但能取得这样的成绩我还是比较高兴的。
最后,要感谢学校为我们提供这次实验机会,也要感谢老师的教导,帮助与支。

8.参考文献

[1] 张磊编著《C语言程序设计教程第2版》 中国铁道出版社
[2] 薛小龙编著《开发日记:深入体验C语言项目开发》清华大学出版社
[3] 刘字君张月琴叶瑶王庆生编著《C+理序设计案例分析》 清华大学出版社