1、学生成绩管理系统学生成绩管理系统 数据结构课程设计数据结构课程设计一、课程设计的内容与目的利用所学数据结构理论知识完成“学生成绩管理系统”的设计。通过课程设计提高学生的思维能力,促进学生的综合应用能力和专业素质的提高。具体包括:了解并掌握数据结构与算法的设计方法,具备初步的独立分析和设计能力;初步掌握软件开发过程的问题分析、系统设计、程序编码、测试等基本方法和技能;提高综合运用所学的理论知识和方法独立分析和解决问题的能力;训练用系统的观点和软件开发一般规范进行软件开发,培养软件工作者所应具备的科学的工作方法和作风。二、课程设计的要求与数据1.系统功能需求分析:1、输入功能:可以输入 40 位同
2、学信息2、增加功能,能增加学生的信息3、浏览功能:完成对全部学生记录浏览4、查询功能:采用散列查找完成按学号查找学生记录5、排序功能:采用直接选择排序,将学生平均成绩从低到高排序输出6、删除功能:可以删除学生信息7、修改功能:可以对学生信息的各项信息进行修改8、插入功能:完成数据的插入9、统计功能:统计出各分数段学生人数(60 分以下,6070,7180,.)2.存储结构设计分析:3.学生的信息:学生的信息采用结构体类型定义,每个元素表示一个学生的信息,包括学号,姓名及数据结构平均成绩 4 个数据项:(1)struct studentchar num11;char name20;int sco
3、re8;float ave;stuN;(2)散列表的结点类型定义:typedef struct node unsigned long int key;struct node*link;HNode;3.源程序如下:#include#include#include/*控制学生记录的容量*/#define N 40#define PR printf(nr%s%s%s%s%s%s%s%s%s%s%s ,stui.num,stui.name,stui.score0,stui.score1,stui.score2,stui.score3,stui.score4,stui.score5,stui.score
4、6,stui.score7,stui.score8,stui.ave)struct studentchar num11;char name20;int score8;float ave;stuN;typedef struct node unsigned long int key;struct node*link;HNode;typedef structint key;/*排序码*/float data;/*其他数据项*/RecNode;/*全新保存函数*/save(int n)/*保存函数,保存n个记录*/FILE*fp;int i;if(fp=fopen(sc.txt,wb)=NULL)/*
5、以输出打开方式,在此前的记录被覆盖*/printf(n不能打开文件n);getch();return NULL;for(i=0;in;i+)if(stui.ave!=0)/*stui.ave=0表此记录已删除*/if(fwrite(&stui,sizeof(struct student),1,fp)!=1)printf(文件输入错误n);fclose(fp);/*加载记录或可以计算记录个数的函数*/load()/*加载记录或可以计算记录个数的函数*/FILE*fp;int i;if(fp=fopen(sc.txt,rb)=NULL)/*以输出打开方式,在此前的记录被覆盖*/printf(n不能
6、打开文件n);getch();return NULL;for(i=0;!feof(fp);i+)fread(&stui,sizeof(struct student),1,fp);fclose(fp);return(i-1);/*返回记录个数*/*一个任务结束时的选择浏览还是返回的函数*/void printf_back()/*一个任务结束时的选择浏览还是返回*/int k,w;printf(nnt-成功-nn);printf(请选择:nnt1).现在浏览全部t2).返回:bb);scanf(%d,&w);if(w=1)browse();else teacher();/*显示数据结构项目函数*/
7、void printf_face()/*显示数据结构项目*/printf(nt学号 姓名t英语 数学 C语言 管理学 信检 体育 近代史 线数 平均分tn);average(int i)/*对第i个记录的分数求平均值*/int j,sum;for(sum=0,j=0;j8;j+)sum+=stui.scorej;stui.ave=sum/8.0;/*学号输入函数*/no_input(int i,int n)/*i表示第i个的学生信息,n表示比较到第n个学生*/int j,k,w1;do w1=0;printf(学号:);scanf(%s,stui.num);for(j=0;stui.numj!
8、=0;j+)/*学号输入函数,作了严格规定*/if(stui.numj9)/*判断学号是否为数字*/puts(Input error!Only be made up of(0-9).Please reinput!n);w1=1;break;if(w1!=1)for(k=0;kn;k+)/*比较到第n个学生*/*排除第i个学生记录即你要修改的*/if(k!=i&strcmp(stuk.num,stui.num)=0)/*判断学号是否有雷同*/puts(该记录已存在.请重新输入!n);w1=1;break;while(w1=1);/*对分数输入*/score_input(int i)int j;p
9、rintf(1.英语 2.数学 3.C语言 4.管理学 5.信检 6.体育 7.近代史 8.线性代数n);for(j=0;j8;j+)printf(score%d:,j+1);scanf(%d,&stui.scorej);/*输入一个记录函数*/input(int i)/*输入一个记录函数*/no_input(i,i);/*调用学号输入函数*/printf(姓名:);scanf(%s,stui.name);score_input(i);/*调用分数输入函数*/average(i);/*调用求平均值函数*/*显示一个记录的函数*/printf_one(int i)/*显示一个记录的函数*/int
10、 j;printf(%11s%-10s,stui.num,stui.name);for(j=0;jnn 1).学号 2.姓名 3).英语 4).数学n 5).C语言 6).管理学 7).信检 8).体育 9).近代史n 10).线性代数 11).all score 12).all data 13).cancel and back);printf(请选择:bb);scanf(%d,&c);if(c13|c13|c2&c10)average(i);/*调用求平均值函数*/puts(nNow:n);printf_face();/*调用显示数据结构项目函数*/printf_one(i);/*修改后的记
11、录让用户确认*/printf(n是否确定?nnt1).确定 2).重新修改 3).不保存返回 bb);/*是否确定*/scanf(%d,&w1);/*选择2则表示这次修改错误要重新修改*/while(w1=2);return(w1);/*返回控制值*/*输入模块*/enter()/*输入模块*/int i,n;printf(输入学生总数(0-%d)?:,N);scanf(%d,&n);/*要输入的记录个数*/printf(n现在输入数据nn);for(i=0;in;i+)printf(nInput%dth student record.n,i+1);input(i);/*调用输入函数*/if(
12、i!=0)save(n);/*调用保存函数*/printf_back();/*一个任务结束时让用户选择是浏览还是返回*/*追加模块*/add()/*追加模块*/int i,n,m,k;FILE*fp;n=load();printf(增加的学生总数(0-%d)?:,N-n);scanf(%d,&m);/*输入要追加的记录个数*/k=m+n;for(i=n;ik;i+)printf(nInput%dth student record.n,i-n+1);input(i);/*调用输入函数*/if(fp=fopen(sc.txt,ab)=NULL)/*以ab方式打开文件,追加保存*/printf(不能
13、打开文件n);return;for(i=n;ik;i+)/*输入出到文件*/if(fwrite(&stui,sizeof(struct student),1,fp)!=1)printf(文件输入错误n);fclose(fp);printf_back();/*一个任务结束时的选择浏览还是返回*/*修改模块*/modify()/*修改模块*/struct student s;FILE*fp;int i,n,k,w0=1,w1,w2=0;n=load();do system(cls);k=-1;/*给用户看全部记录以便确认要修改的记录*/puts_();/*显示-*/printf_face();/*
14、调用显示数据结构项目函数*/for(i=0;in;i+)if(i!=0)&(i%10=0)/*目的是分屏显示*/printf(nnRemember NO.which needed modify.pass any key to contiune .);getch();puts(nn);printf_one(i);/*调用显示一个记录的函数*/puts_();do printf(nn输入修改学号!NO.:);scanf(%s,s.num);/*输入要修改的数据的学号*/for(i=0;in;i+)/*查找要修改的数据*/if(strcmp(s.num,stui.num)=0)k=i;/*找到要修改
15、的记录*/s=stui;/*把stui(即当次修改的学生记录)备份给s,以便用户反悔时恢复名誉*/if(k=-1)printf(nn不存在!重新输入);while(k=-1);/*当K=-1表示没有找到*/printf_face();/*调用显示数据结构项目函数*/printf_one(k);/*调用显示一个记录的函数*/w1=modify_data(k,n);/*修改学生记录并且返回保存控制值w1,w1=1则表示用户已确认修改*/if(w1=1)/*W1等于1时则表示用户确定这次修改*/printf(n-成功-.nn是否修改其他?nnt1).是 2).保存返回t bb);scanf(%d,&
16、w0);w2=1;/*来控制保存,使w2=1是标记已有过修改*/else w0=0;if(w2=1)stuk=s;/*走到这里是由于用户没有确认这次修改(在调用修改函数w1=modify_data(k,n);时没有确认).使W0=0,为了让终止循环,stuk=s,则把备份的s恢复给stuk(即当次修改的),这样的好处是确保在此之前修改过的成功保存,而本次(用户没有确认的)不修改*/if(w0!=1&w2=1)/*W0不等于1则表示正常返回,w2=1表示在此之前有过修改,这时就保存用户已确认修改的并返回*/save(n);/*w2不等于1表示在此次之前没有修改过(即:第一次),而又反悔这次修改,
17、则不保存返回*/while(w0=1);teacher();/*删除模块*/del()/*删除模块*/struct student s;FILE*fp;int i,j,n,k,c,w0=1;n=load();do system(cls);k=-1;/*给用户看全部记录以便确认要删除的记录*/puts_();printf_face();/*调用显示数据结构项目函数*/for(i=0;in;i+)if(stui.ave!=0)if(i!=0)&(i%10=0)/*目的是分屏显示,每10个一屏*/printf(nnRemember NO.which needed del.pass any key t
18、o contiune .);getch();puts(nn);printf_one(i);/*调用显示一个记录的函数*/puts_();do printf(nn输入删除学号!NO.:);scanf(%s,s.num);/*输入要修改的数据的学号*/for(i=0;in;i+)/*查找要修改的数据*/if(strcmp(s.num,stui.num)=0)k=i;/*找到要修改的记录的下标赋给K*/s=stui;if(k=-1)printf(nn不存在!重新输入);/*K=-1,表示没有找到相同之的*/while(k=-1);puts(n);printf_face();/*调用显示数据结构项目函
19、数*/printf_one(k);/*调用显示一个记录的函数*/printf(n是否确定?nt1).是 2).否且删除其他 3).保存全部返回 bb);scanf(%d,&c);if(c=1)stuk.ave=0;/*stuk.ave=0用来标识这个记录是要删除的.保存时则不保存stuk.ave=0的数据*/printf(nn-成功-.nn是否重输?nt1).是 2).返回菜单t bb);/*问是否继续*/scanf(%d,&w0);if(c=3)w0=0;/*w0=0不删除直接返回*/if(w0!=1&c!=3)/*只有当确认删除后返回才保存,不删除直接返回则不保存,且不保存在此之前删除过的
20、记录*/save(n);while(w0=1);teacher();/*返回教师介面*/*浏览(全部)模块*/browse()/*浏览(全部)模块*/int i,j,n;n=load();/*加载记录*/system(cls);puts_();printf_face();/*调用显示数据结构项目函数*/for(i=0;ikey=k;p-link=NULL;ti=p;printf(n inserted%lun,k);return(1);elsep=ti;while(p!=NULL)if(p-key=k)printf(n retrieval%lun,k);return(0);else if(p-l
21、ink!=NULL)p=p-link;elsep-link=(HNode*)malloc(sizeof(HNode);p=p-link;p-key=k;p-link=NULL;printf(n inserted%lun,k);return(1);getch();HNode*linksearch(HNode*t,char k)/*在用拉链法处理冲突的散列表t中查找关键字为给定值k的记录*/HNode*p;int i;i=h(k);if(ti=NULL)return(NULL);p=ti;while(p!=NULL)if(p-key=k)printf(%lun,p-key);return(p);e
22、lse p=p-link;return(NULL);search()/*查找模块*/int i,n,k,w1=1,w2,w3,w4;struct student s;n=load();do do k=-1;printf(nn输入查找学号!NO.:);scanf(%s,s.num);/*输入要修改的数据的学号*/printf_face();/*调用显示数据结构项目函数*/for(i=0;in;i+)/*查找要修改的数据*/if(strcmp(s.num,stui.num)=0)k=i;/*找到要修改的记录*/printf_one(k);break;/*调用显示一个记录的函数*/if(k=-1)p
23、rintf(nn不存在!请重新输入);printf(nn是否确定?nt1).是 2).否且返回 bb);scanf(%d,&w1);while(k=-1&w1=1);/*如果w1不等于1则直接返回*/w4=0;w3=0;if(k!=-1)/*k不等于-1表示找到,如果找到则选择操作*/printf(nn请选择:nt1).查找另一个数据 2).修改 3).删除 4).返回目录 bb);scanf(%d,&w2);switch(w2)case 2:w3=modify_data(k,n);break;/*调用修改数据函数*/case 3:printf(n是否确定?nt1).是 2).否且返回 bb)
24、;scanf(%d,&w4);if(w4=1)stuk.ave=0;/*表示删除*/break;if(w3=1|w4=1)save(n);printf(nn-成功-.);printf(nn请选择:nt1).查找另一个数据 2).返回 bb);scanf(%d,&w2);while(w2=1);teacher();/*插入模块*/insert()/*插入模块*/int i,j,n,c;struct student s;n=load();puts(n输入一个数据.n);do input(n);/*输入到第n个记录,即插入到最后*/printf_face();printf_one(n);printf
25、(nn是否确定?nnt1).是t2).取消重输t3).不保存返回 bb);scanf(%d,&c);if(c=1)for(j=0;jj;i-)if(stui.avestui-1.ave)s=stui-1;stui-1=stui;stui=s;save(n+1);printf_back();else if(c!=2)teacher();while(c=2);/*排序模块(按平均成绩)*/void sift(RecNode r,int t,int w)/*用筛选法调整堆*/int i,j;RecNode x;i=t;x=ri;j=2*i+1;while(j=w)if(jrj+1.key)j+;if
26、(x.keyrj.key)ri=rj;i=j;j=2*j+1;else break;ri=x;void heapsort(RecNode r,int n)/*堆排序*/int i;RecNode x;for(i=n/2-1;i=0;i-)sift(r,i,n-1);for(i=n-1;i0;i-)x=r0;r0=ri;ri=x;sift(r,0,i-1);/*排序模块(按平均成绩)*/order()/*排序模块(按平均成绩)*/int i,j,k,n;struct student s;n=load();for(i=0;in-1;i+)/*选择法排序*/k=i;for(j=i+1;jn;j+)i
27、f(stuj.avestuk.ave)k=j;s=stui;stui=stuk;stuk=s;save(n);puts(nn);printf_back();/*统计模块*/void fenduantongji()int k,u,n,i,j,w1=1,w2;int a,b,c,d,e;a=0;b=0;c=0;d=0;e=0;printf(1.英语 2.数学 3.C语言 4.管理学 5.信检 6.体育 7.近代史 8.线性代数 9.平均分n);printf(请输入要统计的科目:);scanf(%d,&u);if(u=8)n=u;for(i=0;i=90)a=a+1;else if(k=80)b=b
28、+1;else if(k=70)c=c+1;else if(k=60)d=d+1;else if(k60)e=e+1;else n=u;for(i=0;i=90)a=a+1;else if(k=80)b=b+1;else if(k=70)c=c+1;else if(k=60)d=d+1;else if(k60)e=e+1;printf(学生成绩在 90100 间有:n%dn,a);printf(学生成绩在 8089 间有:n%dn,b);printf(学生成绩在 7079 间有 :n%dn,c);printf(学生成绩在 6069 间有 :n%dn,d);printf(低于60的有:n%dn,
29、e);printf(n是否继续?nnt1).是 2).否 bb);scanf(%d,&w1);if(w1=1)fenduantongji(w1);elseteacher();/*教师界面*/teacher()/*教师界面*/int n,w1;do system(cls);/*清屏*/puts(tt*MENU*nn);puts(tttt1.输入新数据);puts(tttt2.添加数据);puts(tttt3.修改数据);puts(tttt4.删除数据);puts(tttt5.浏览全部);puts(tttt6.学号查询);puts(tttt7.插入数据);puts(tttt8.按平均分排序);pu
30、ts(tttt9.分段统计);puts(tttt10.退出);puts(tttt11.返回主界面);puts(nntt*n);printf(请选择序号:(1-11):bb);scanf(%d,&n);if(n11)/*对选择的数字作判断*/w1=1;getchar();else w1=0;while(w1=1);/*选择功能*/switch(n)case 1:enter();break;/*输入模块*/case 2:add();break;/*追加模块*/case 3:modify();break;/*修改模块*/case 4:del();break;/*删除模块*/case 5:browse
31、();break;/*浏览模块*/case 6:search();break;/*查找模块*/case 7:insert();break;/*插入模块*/case 8:order();break;/*排序模块*/case 9:fenduantongji();break;/*统计模块*/case 10:exit(0);/*退出*/case 11:menu();/*返回主界面*/getch();/*密码函数*/distin()/*密码函数*/int f;char mima=gdut09;char mi6;printf(输入密码:);scanf(%s,mi);if(strcmp(mima,mi)=0
32、)teacher();else printf(密码错误!n);printf(nn请选择:nt1).目录 2).退出 bb);scanf(%d,&f);switch(f)case 1:menu();break;case 2:exit(0);break;/*学生界面*/st()/*学生界面*/int i,n,k,w1=1,w2,w3,w4;struct student s;n=load();do system(cls);do k=-1;printf(nn请输入学号 NO.:);scanf(%s,s.num);printf_face();for(i=0;in;i+)if(strcmp(s.num,s
33、tui.num)=0)k=i;printf_one(k);break;if(k=-1)printf(nn不存在!重输入);printf(nn是否重新输入?nt1).是 bb);scanf(%d,&w1);while(k=-1&w1=1);w4=0;w3=0;if(k!=-1)printf(nn请选择:nt1).返回目录 bb);scanf(%d,&w2);switch(w2)case 1:menu();break;case 3:printf(n是否确定?nt1).否且返回 bb);scanf(%d,&w4);if(w4=1)stuk.ave=0;break;if(w3=1|w4=1)save(
34、n);printf(nn-成功-.);printf(nn请选择:nt1).返回 bb);scanf(%d,&w2);while(w2=1);menu();/*主界面*/menu()/*主界面*/int c;system(cls);/*清屏*/printf(n);printf(n);printf(n);printf(n);printf(n);printf(n);printf(n );printf(n );printf(n );printf(n );printf(n );printf(n );printf(n );printf(n );printf(n );getch();system(cls);
35、/*清屏*/printf(n);printf(n);printf(n);printf(n);printf(n);printf(n);printf(n);printf(nttt 欢迎使用学生成绩管理系统nn);puts(tt目录nn);printf(tt 1.教师登陆n);printf(tt 2.学生登录n);printf(tt 3.退出);puts(nnttn);scanf(%d,&c);switch(c)case 1:distin();break;case 2:st();break;case 3:exit(0);break;/*主函数*/main()menu();getch();三、实验结果
36、和数据处理:1.、运行该程序,初始界面为欢迎界面:运行该程序,初始界面为欢迎界面:2、输入数字、输入数字 1,按,按 enter 后,然后输入密码后,然后输入密码 gdut09,进入教师菜单:,进入教师菜单:3、教师界面:、教师界面:4、输入、输入 1,选择输入功能,再输入,选择输入功能,再输入 3 个学生信息:个学生信息:5 5、输入、输入 1 1,浏览全部数据:,浏览全部数据:6 6、返回教师界面,输入、返回教师界面,输入 3 3,进行修改:,进行修改:7 7、返回教师界面,输入、返回教师界面,输入 2 2,进行追加数据,进行追加数据8 8、返回教师界面,输入、返回教师界面,输入 4 4,
37、进行删除数据:,进行删除数据:9 9、返回教师界面,输入、返回教师界面,输入 5 5,进行浏览:,进行浏览:1010、返回教师界面,输入、返回教师界面,输入 6 6,进行查找:,进行查找:1111、返回教师界面,输入、返回教师界面,输入 7 7,进行插入数据:,进行插入数据:1212、进入教师界面后,输入进行按平均成绩、进入教师界面后,输入进行按平均成绩(从小到大从小到大)排序:排序:1313、在教师界面输入、在教师界面输入 9 9,完成分段统计功能:,完成分段统计功能:1414、返回主界面,输入、返回主界面,输入 2 2,进入学生界面,按学号进行查找学生成绩:,进入学生界面,按学号进行查找学
38、生成绩:四、参考文献:数据结构 C 语言 严蔚敏 清华大学出版社c 语言程序设计 谭浩强 清华大学出版社数据结构 高教出版社 数据结构习题 李春保 清华大学出版社数据结构习题 严蔚敏 清华大学出版社c 语言与数据结构 王立柱 清华大学出版社数据结构(C 语言篇)习题与解析)李春葆 清华大学出版社 五、总结:通过这次的课程设计,做一个程序设计,真的不容易。很多都不懂得怎么去做,虽然最后做完了这个课程设计,但是有些并不能满足老师的要求,而且因为有很多不懂的地方,所以发了很多时间去看书及请教同学。虽然不能说这个程序是完全自己做的,但是我也有很认真的去寻找错误并修改。我觉得这次自己也有一点点进步的,当自己发现了错误,会修改了也是一种进步吧。看到自己进步,其实也挺欣慰的,至少努力没白费,还是学到了一点知识的。就像我知道了怎样返回某些函数。开始的时候本来是想要用堆排序进行学生平均分排序,可是做了很久,又问同学,最后还是不会做,虽然在懂堆排序,却不会用。所以只好用直接选择排序。而在分段统计中,原来有很多错误,不明确。之后我跟同学就把它改成按科目及平均分来统计,可是看了很久,改了很多次,其他分数段的没有错误,但是在 60 分以下的统计却不能实现,不知道该怎样去改。