一,需求分析:
用数组或链表数据结构完成一个学生成绩管理系统,此系统的具体功能要求如下:
(1)学生信息录入功能
1)用户从键盘输入每个学生的信息:学号、姓名、性别、数学、英语、政治、程序设计基础、物理五门课成绩。
2)可插入一个或多个学生信息到当前编辑的班级数据中。
3)可删除一个或多个学生信息。
(4)查询功能
1)浏览所有学生信息; 2)按学号查询学生信息; 3)按姓名查询学生信息;
4) 查询一个班总成绩和平均成绩;
5) 查询一个班某一门课总成绩和平均成绩;
6)查询某一门课分数段( <60,60-69,70-79,80-,>90)学生数。
(5)报表输出功能
1) 按学号输出一个班学生信息:学号、姓名、性别、数学、英语、政治、程序设计基础、物理成绩和总成绩,到屏幕和文件。 2) 按总成绩输出从高到低输出学号、姓名信息。
注:以上功能以菜单形式供用户使用,并有一定的容错功能。
二,功能描述
整体框架:
整个学生成绩管理系统采用链表作为基本数据结构,创建一个类student用于保存学生的数据且是链表中的一个节点。类list作为保存整个链表之用。主函数通过switch语句来根据用户的需要连接各个模块,以实现用户的需要。 模块基本介绍: 1. 用户输入模块
在此模块中,用户将根据菜单提示结合自己的需求输入一个0~11的值,来实现一定的功能。
2. 学生信息录入模块
此模块可以让用户从键盘输入每个学生的信息:学号、姓名、性别、数学、英语、政治、程序设计基础、物理五门课成绩。用户可插入一个或多个学生信息到当前编辑的班级数据中。 用户可删除一个或多个学生信息。 3. 查询功能模块
在此模块里,用户可实现以下操作:1.浏览所有学生信息;2.按学号查询学生信息;3.按姓名查询学生信息;4.查询一个班每个人的总成绩和平均成绩; 5.查询一个班某一门课每个人的总成绩和平均成绩;6)进行成绩的统计分析:包括总人数,每门课的最高成绩、最低成绩、平均成绩、各个分数段的人数(100-90、-80、79-70、69-60、59-50、50以下)、及格人数。 4. 报表输出功能模块 在此模块中,用户可以浏览所有学生的信息,或者可以按学号输出一个班学生信息:学号、姓名、性别、数学、英语、政治、程序设计基础、物理成绩和总成绩,
到屏幕和文件。也可以按总成绩输出从高到低输出学号、姓名信息。 模块图
值 1,3,4 学生信息录入 模块
三,总体设计
开始 m 值7,2,6,5 值8 查询功能模块 输出功能模块 用户输入,并将值保存m 结束 主要功能模块的算法设计思路:
1. 用户输入模块设计
提示用户输入一个0~8的值,并存储在一个整型变量m中。 2. 学生信息录入模块设计
通过应用list中的instu()函数,来新建一个链表中的节点,即一个新的学生信息,来进行成绩的录入功能。成绩修改功能,可以根据姓名或学号进行查询并修改相应的课程的成绩,使用了void search(char s[10],int)和void search1(char s[20],int)函数进行操作。search函数根据姓名查找,search1函数根据学号进行查找。因为学号和姓名,都是存储在字符数组中的,所以都是通过字符串的比较进
行查找的。然后根据整形参数进行对应的课程成绩的修改。成绩删除功能,也是可以根据姓名或学号进行删除,查询的算法和成绩修改功能的查询方法是一样的,当找到要删除的节点时,因为节点都是在堆内存中保存的,所以可以直接delete掉,并将前一个节点的next指针指向被删掉的节点的next指针所指向的节点。
3. 查询功能模块
可以根据姓名或学号进行查找,搜索方法和前几个模块相同。通过outstu1(char *n)和outstu(char *n)来进行输出。总成绩和平均成绩的查询通过函数void outsum(char *)和void outsum1(char *)来完成。通过函数scanall()来浏览所有学生的信息。通过函数think()来进行成绩的统计分析。
4. 报表输出功能模块
通过建立一个新的类class stucopy用于拷贝student的数据,并实现排序功能。创建一个stucopy stu[M]数组,将原链表的数据拷贝与数组中,然后用选择排序方法将数组排序,然后用output按照标准的格式输出。 四,调试分析
调试是整个程序编写过程中十分重要也是很困难的一部分,在这个过程中用了不少的时间进行程序的调试,在调试过程中遇到的相关问题如下:
一、语法错误
1、语句的最后忘记了加上“;”,使程序发生错误。
2、把“<<”与“>>”写反,以及字符与字符串的操作问题。 3、函数的返回值问题。 二、逻辑错误
1、文件的写入与输出,刚开始对文件的操作不太明白,不能很好的操作文件,其中最大的问题是对已存在的文件读取问题,通过“显示全部学生成绩” 将数据从文件中读取,可是在使用过程中总是出现输出错误,出现乱码。
2、内存的分配问题,这也是困惑了很久的问题。对于我们初学者来说对内存的分配和释放是比较抽象和模糊的难题,本来使用链表的方式存储数据,然而待到排序时出现了交换数据困难的现象,以及分配空间繁琐、释放空间不及时等问题,造成空间浪费,使得程序运行效率低的问题。因此最后采用了顺序存储记录的方式,解决了前述问题。 五,测试结果 1,主界面
2,录入记录
3,查询记录
4, 修改记录
5, 删除记录
6, 统计分析记录
7, 总成绩和平均成绩查询记录
8, 浏览记录
9, 排序记录
六,课程设计的总结
五个星期的课程设计,有些疲劳和困倦,但带来很多的收获。C++已经学了一个学期了,有许多知识都存在似懂非懂的现象,这种现象通过实际的上机操作,已经减少了许多。对这些知识也有了更深的理解和很好的掌握。也有很多理论上说得过去的代码,但到了实际操作,却是行不通的。这种困惑,许多已经通过实际操作解决了,并能够深刻认识。
在课程设计之前,因为有了综合实验的经验与教训,明白了写代码这一步是非常重要的,因为当你把代码输入电脑,并用编译器将其运行,发现通过不了,再回头检查并找出问题,这是一件非常辛苦的事情,也很浪费时间。于是在课程设计的时候,花费很多的时间来规划与写代码,将要实现的内容分析清楚,才把代码输入电脑。我觉得写程序,应该先找到该程序中的核心地方,用多种方法来实现该核心,这才可能避免等到发现逻辑上或者编译器不支持上的错误,才来想补救的措施,这样花费时间是很不值得的。
此次任务的完成,也体现出同学之间的团结精神。实践是检验真理的唯一标准。没有实践,就不会发现和深刻体会它的真实所在。只有通过检验的真理,在自己的心里,才会认可它的真实性。面向对象程序设计的完成,使我们懂得了真理的重要性,理论和实际的相结合,才能真正把握所学和所掌握的知识。 八,附录
源代码:
#include class stucopy//此类用于拷贝student的数据,用于排序功能的实现 { public: char id[20]; char sex[10]; char name[10]; double grade[5]; double sumsum;//总成绩 double average;//平均成绩 }; class student//用于保存学生信息的类 { friend class list; public: char id[20];//保存学号 char sex[10];//保存性别 char name[10];//保存名字 double grade[5];//保存成绩 student() { next=0; for (int i=0;i<20;i++) id[i]=0; for (i=0;i<10;i++) sex[i]=0; for (i=0;i<10;i++) name[i]=0; } void s(); void setid(char id1[20]) { for(int i=0;i<20;i++) id[i]=id1[i]; } void setsex(char sex1[10]) { for(int i=0;i<10;i++) sex[i]=sex1[i]; } void setname(char name1[10]) { for(int i=0;i<10;i++) name[i]=name1[i]; } void setgrade(double grade1[5]) { for(int i=0;i<5;i++) grade[i]=grade1[i]; } student *next;//next指向下一个学生,构成链表 char * outid(){return id;}; char * outsex(){return sex;}; char * outname(){return name;}; double outsum() { double sum=0; for(int i=0;i<5;i++) sum+=this->outgrade(i); return sum; } double outav(){return this->outsum()/5;} double outgrade(int i){return grade[i];}; void intgrade(int); }; void student::intgrade(int j)//用于修改学生的成绩 { switch (j) { case 1: cout<<\" 请输入数学成绩:\\n\"; cin>>grade[0];break; case 2: cout<<\"请输入英语成绩:\\n\"; cin>>grade[1];break; case 3: cout<<\"请输入政治成绩:\\n\"; cin>>grade[2];break; case 4: cout<<\"请输入程序设计基础成绩:\\n\"; cin>>grade[3];break; case 5: cout<<\"请输入物理成绩:\\n\"; cin>>grade[4];break; } } void student::s()//用于录入学生的信息 { cout<<\"请输入学号:\\n\"; cin>>id; cout<<\"请输入姓名:\\n\"; cin>>name; cout<<\"请输入性别:\\n\"; cin>>sex; cout<<\"请输入数学成绩:\\n\"; cin>>grade[0]; cout<<\"请输入英语成绩:\\n\"; cin>>grade[1]; cout<<\"请输入政治成绩:\\n\"; cin>>grade[2]; cout<<\"请输入程序设计基础成绩:\\n\"; cin>>grade[3]; cout<<\"请输入物理成绩:\\n\"; cin>>grade[4]; } class list//此类为链表 { private: double high[5],low[5]; public: student *last,*first;//链表的开头和结尾 double totoal; list(){last=0;first=0;}; ~list(); void instu();//新建一个学生的数据 void outstu(char *);//根据姓名输出一个学生的信息 int delstu(char *n);//根据姓名删除一个学生的信息 void outstu1(char *);//根据学号输出一个学生的信息 int delstu1(char *n);//根据学号删除一个学生的信息 void outsum(char *);//根据姓名输出一个学生的总成绩和平均成绩 void outsum1(char *);//根据学号输出一个学生的总成绩和平均成绩 void think();//用于输出班级成绩的统计分析 void search(char s[10],int);//根据姓名修改一个学生的成绩 void search1(char s[20],int);//根据学号修改一个学生的成绩 double hi(int i);//求某门课的最高分 double lo(int i);//求某门课的最低分 void av(int i);//求某门课的平均分 void ev(int i);//用于班级成绩统计分析的人数分布输出 void scanall();//输出所有学生的信息 }; list::~list()//析构函数,将所有创建的学生对象删掉 { if(first!=0) { student *p=first,*temp; while(p!=NULL){ temp=p; p=p->next; delete temp; cout<<\"ok\\n\"; }}} void list::instu() { student *p=new student(); p->s(); if(first==0){first=last=p;}else{last->next=p;last=p;} } void list::outstu(char *n) { if(first==0) {cout<<\"班级无成员!查无此人!\"< cout< if(first==0) {cout<<\"班级无成员!查无此人!\"< cout< ex()< if(first==0) {cout<<\"无数据!\"< else for(;temp->next!=NULL;temp=temp->next) {if(strcmp(temp->next->outname(),n)==0) {p=temp->next;temp->next=temp->next->next;delete p; cout<<\"\\n删除成功\\n\";return 0;}} cout<<\"\\n查无此人,删除失败\\n\"; return 0; } int list::delstu1(char *n) { if(first==0) {cout<<\"无数据!\"< {if(strcmp(temp->next->outid(),n)==0) {p=temp->next;temp->next=temp->next->next;delete p; cout<<\"\\n删除成功\\n\";return 0;} else temp=temp->next;} cout<<\"\\n查无此人,删除失败\\n\"; return 0; } void list::think() { if(first==0) {cout<<\"无数据!\"< student *p=first; while (p!=NULL) { p=p->next; i++; } totoal=i; cout<<\"人数:\"<cout<<\"最高分:\"<cout<<\"英语\\n\"; cout<<\"最高分:\"<
因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- fenyunshixun.cn 版权所有 湘ICP备2023022495号-9
违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务