问题描述
解决思路
遇到问题和解决办法
核心程序
总结
一、问题描述 学生成绩管理系统:将学生的基本信息和成绩录入,根据学生的基本信息来实现以下功能:(1)实现对学生成绩和基本信息的添加、删除、修改、查找;(2)实现对学生成绩的统计(最高分、最低分、及格率);(3)通过学号和姓名来实现对成绩的查询;(4)实现对学生成绩(单科成绩、总分)的排序;(5)实现对学生基本信息的显示(学生基本信息包括:姓名、学号、院系、年级、班级、单科成绩)。
二、解决思路 解决方法:首先通过定义函数,将想要实现的功能放在函数里面实现,然后将数据(即学生基本信息和成绩)保存到结构体数组里面,最后对基本的输入输出语句、顺序结构、选择结构、循环结构、关键字(如switch、break等)、函数的调用等相互穿插、嵌套使用来实现基本的框架结构,最终实现该系统。 解题思路:先把题目要求的实现的功能先列出来,看着更直观清晰,把需要用到的知识提前过一遍。若是把要实现的功能放在一个函数里面,可能因为信息量太大而出错,所以选择把要求实现的分别放在不同的函数里面,这样看起来也更清晰。为了使程序使用起来更方便,所以就需要创建一个主菜单,把所有功能都显示出来。又因为main()函数使每一个程序的入口处和结束的地方,所以就选择把这个主菜单放入到main()函数里面,通过switch语句来实现主菜单及函数的调用,但由于系统要实现的功能过多,所以把后面定义的函数,提前在主函数前面声明,防止因为主函数内信息量过大而出错。最后就是写程序的时候,先将实现功能的函数定义,然后在主函数里调用函数,将需要实现的功能添加到switch语句里面,每添加一个功能执行一次来验证代码的准确性,防止因一次性添加导致出现一系列问题。
三、遇到问题和解决办法 遇到问题(1):程序执行时只调用了一个功能就自动退出了。 解决方法:将主菜单(switch语句)放在一个死循坏结构里面,让这个switch语句一直可以执行,然后在循环里面,switch语句的下面加一个条件判断,通过询问用户是够继续操作,来决定此程序是否结束,对于程序的结束操作,通过break来实现。 遇到问题(2):调用实现增加学生的基本信息和成绩的功能时,用一个新的结构体数组实现学生基本信息和成绩的录入,但并未添加到原有的结构体数组里面。 解决方法:在实现添加功能的函数里面,将原来用来保存学生基本信息和成绩的结构体数组的长度延长,将这个用来保存要添加的学生信息和成绩的结构体数组,从数组第一个元素开始一一赋值给原来的结构体数组延长的部分,通过for循环来实现这个赋值过程。然后在switch语句中调用添加函数的语句后面将原来结构体数组的长度扩大为现在增加后的长度。 遇到问题(3):调用实现删除学生的基本信息和成绩的功能时,根据姓名找到想要删除的学生的信息,然后在实现删除功能的函数里面进行了删除,但并未将原有结构体数组里面的这个学生的信息删除。 解决方法:在实现删除功能的函数里面,得到所要删除的学生信息在原来的结构体数组里面所占的下标,将原来用来保存学生基本信息和成绩的结构体数组的长度缩短一位,从所要删除的学生信息的下标开始,将后面的学生信息一一赋值给前面,实现对所要删除的学生信息的覆盖,达到删除的效果。最后在switch语句中调用实现删除功能的函数语句后面将原来的结构体数组的长度缩短一位。 遇到问题(4):在计算及格率时,最后输出的结果时小数,而不是以百分率的形式输出。 解决方法:在输出语句中将计算出来的及格率乘以100,然后在加上“%%”。
四、核心程序 (1)学生信息录入函数: struct Student* Input(struct Student pArr,int len) { pArr=(struct Student)malloc(len*sizeof(struct Student)); int i; for(i=0;i<len;i++) { printf(“请输入第%d个学生的姓名\n”,i+1); scanf("%s",pArr[i].Name); printf(“请输入第%d个学生的学号\n”,i+1); scanf("%d",&pArr[i].Id); printf(“请输入第%d个学生所属的学院\n”,i+1); scanf("%s",&pArr[i].Department); printf(“请输入第%d个学生所属的年级\n”,i+1); scanf("%s",&pArr[i].Grade); printf(“请输入第%d个学生所属的班级\n”,i+1); scanf("%s",&pArr[i].Class); printf(“请输入第%d个学生的C语言成绩\n”,i+1); scanf("%f",&pArr[i].Score[0]); printf(“请输入第%d个学生的高数成绩\n”,i+1); scanf("%f",&pArr[i].Score[1]); printf(“请输入第%d个学生的英语成绩\n”,i+1); scanf("%f",&pArr[i].Score[2]); pArr[i].Total=pArr[i].Score[0]+pArr[i].Score[1]+pArr[i].Score[2]; pArr[i].Average=pArr[i].Total/3.0; } return pArr; }
(2)学生信息增加函数: void Add(struct Student *pArr,int len) { int i; printf(“请输入添加学生的人数:\n”); scanf("%d",&k); struct Student p=NULL; p=(struct Student)malloc(sizeof(struct Student)*k); for(i=0;i<k;i++) { printf(“请输入第%d个学生的姓名\n”,i+1); scanf("%s",p[i].Name); printf(“请输入第%d个学生的学号\n”,i+1); scanf("%d",&p[i].Id); printf(“请输入第%d个学生所属的学院\n”,i+1); scanf("%s",&p[i].Department); printf(“请输入第%d个学生所属的年级\n”,i+1); scanf("%s",&p[i].Grade); printf(“请输入第%d个学生所属的班级\n”,i+1); scanf("%s",&p[i].Class); printf(“请输入第%d个学生的C语言成绩\n”,i+1); scanf("%f",&p[i].Score[0]); printf(“请输入第%d个学生的高数成绩\n”,i+1); scanf("%f",&p[i].Score[1]); printf(“请输入第%d个学生的英语成绩\n”,i+1); scanf("%f",&p[i].Score[2]); p[i].Total=p[i].Score[0]+p[i].Score[1]+p[i].Score[2]; p[i].Average=p[i].Total/3.0; } Output(pArr,len); Output(p,k); for(int n=len,l=0;n<len+num;n++,l++) { pArr[len]=p[l]; } Output(pArr,len+k); }
(3)学生信息删除函数: void Delete(struct Student *pArr,int len) { int i,num; char Name[20]; printf(“请输入您要删除的学生信息的学生的姓名:\n”); scanf("%s",Name); for(i=0;i<len;i++) { if(strcmp(pArr[i].Name,Name)==0) { num=i; } } for(i=num;i<len-1;i++) { pArr[i]=pArr[i+1]; } Output(pArr,len-1); }
(4)学生信息查找函数: void Seek(struct Student *pArr,int len) { int i,order,Id,num; char Name[20]; printf(“1 输入姓名查询学生成绩\n”); printf(“2 输入学号查询学生成绩\n”); while(1) { int t; printf(“请输入您要选择查询成绩的方式:\n”); scanf("%d",&order); switch(order) { case 1: { printf(“请输入您要查找的学生成绩的学生的名字:\n”); scanf("%s",Name); for(i=0;i<len;i++) { if(strcmp(pArr[i].Name,Name)0) { num=i; } } Output(&pArr[num],1); } break; case 2: { printf(“请输入您要查找的学生成绩的学生的学号:\n”); scanf("%d",&Id); for(i=0;i<len;i++) { if(pArr[i].IdId) { num=i; } } Output(&pArr[num],1); } break; default : printf(“您输入的指令不合法!\n”); break; } printf(“您是否想要继续进行查询学生成绩的操作?如果不是,请输入1结束此操作!或者输入其它任意字符继续操作\n”); scanf("%d",&t); if(t==1) break; } }
(4)学生信息修改函数: void Change(struct Student *pArr,int len) { char Name[20]; int i,num; printf(“请输入您需要修改的学生的信息的学生的姓名:\n”); scanf("%s",Name); for(i=0;i<len;i++) { if(strcmp(pArr[i].Name,Name)==0) { num=i; } } printf(“请输入学生的姓名:\n”); scanf("%3s",pArr[num].Name); printf(“请输入学生的学号:\n”); scanf("%5d",&pArr[num].Id); printf(“请输入学生的所在的学院:\n”); scanf("%7s",&pArr[num].Department); printf(“请输入学生所属的年级:\n”); scanf("%3s",&pArr[num].Grade); printf(“请输入学生所属的班级:\n”); scanf("%5s",&pArr[num].Class); printf(“请输入学生的C语言成绩:\n”); scanf("%5.2f",&pArr[num].Score[0]); printf(“请输入学生的高数成绩:\n”); scanf("%5.2f",&pArr[num].Score[1]); printf(“请输入学生的英语成绩:\n”); scanf("%5.2f",&pArr[num].Score[2]); pArr[num].Total=pArr[num].Score[0]+pArr[num].Score[1]+pArr[num].Score[2]; pArr[num].Average=pArr[num].Total/3.0; Output(pArr,len); }
(5)学生总成绩排序函数: void ScoreTotal(struct Student *pArr,int len) { struct Student temp; for(int i=0;i<len-1;i++) { for(int j=0;j<len-1-i;j++) { if(pArr[j].Total<pArr[j+1].Total) { temp=pArr[j]; pArr[j]=pArr[j+1]; pArr[j+1]=temp; } } } Output(pArr,len); }
五、总结 经过这次课程设计,我学到了很多东西: 首先对于项目的选择我纠结了一会但最终决定做一个学生成绩管理系统,因为这个项目应该是很贴近大学生活的。设计过程是很艰难的,从最开始的大致思路到具体的程序代码落实,这期间远比想象的困难。我的解决思路是把问题细分,遇到有不会的点,或者无从下手的点,我会仔细思考到底是哪里不会,而非浮于表面,泛泛的想“这个地方不会”。当然,有了这种思维是解决问题的前置条件,但是有了这个思维,是不能保证你代码就一定能跑起来的。编程的实现过程中,我因为一些知识掌握的不牢固,所以经常去翻书。而且在编写代码的过程中我几乎是关键地方必有标注,这点对于我之后对程序的检查有着很大的便利,同时也能理清楚思路,在实现和用户做交互的过程中,把界面做的简洁,易懂而且让用户即使不看源码也能轻松的将数据成功的输入,这就需要在输出时考虑好可能出现的问题,从而把界面做的简单易懂。 在完成课程设计后我对于自己学习的c语言有了更加明确地认识,原来自己可以写出非常贴近生活的代码,这也更加坚定了我要学好c语言的决心。写这个课程设计对我的c语言的基础知识的掌握更加深刻,写课程设计也算是帮助自己复习了。做这个项目也算让我对C语言的掌握又提高了一个层次,是我对编程语言的兴趣更加浓厚。
|