C语言实验大作业学生成绩管理.docx
- 文档编号:11697250
- 上传时间:2023-03-30
- 格式:DOCX
- 页数:26
- 大小:523.95KB
C语言实验大作业学生成绩管理.docx
《C语言实验大作业学生成绩管理.docx》由会员分享,可在线阅读,更多相关《C语言实验大作业学生成绩管理.docx(26页珍藏版)》请在冰豆网上搜索。
C语言实验大作业学生成绩管理
学院
班级
学号
姓名
/*在后面的文档编写中,请你不要修改各个标题的内容,从而确保报告内容和风格一致。
完成全部内容后,你只需要在上面的目录上右键“更新域”,选择“只更新页码”就可以更新正确的目录页码。
注意:
目录的左边距为6.5厘米。
*/
1摘要
1.1设计题目
学成绩管理程序
1.2设计内容
为了便于对学生星系进行管理,这里设计了学生信息管理程序。
该程序主要通过对链表的相关操作运用菜单的形式实现对学生基本信息的管理。
首先用户要输入三个学生的基本信息,程序即据此建立了一个有三个学生的链表,每个结点包括学号、姓名、3门课的成绩(英语、数学、计算机,其中成绩精确到小数点后两位)。
菜单为:
1.显示。
(即显示所建立的链表及当前链表内容)
2.排序。
(即将用户所输入的学生信息按学号大小对原有链表内容进行排序,并将经排序所产生的新链表展示给用户)
3.插入。
(用户根据需要可增加原链表中学生的数量,输入一个学生的基本信息,即将其插入原链表中,且新链表按学号有序排列并展现给用户)
4.查找。
(输入一个学号,输出各种成绩)
5.删除。
(输入一个学号,从链表中删除该学生,并展示新链表)
6.统计。
(若按1,则输入该学生的学号统计该学生的总分及平均分;若按2,则输入课程(1.英语2.数学3.计算机)求该门课程的总分及平均分)
7.存盘。
(将建立起来的链表以文件的形式存储)
8.读入。
(将原来已将存盘的文件读入内存,进行管理)
1.3开发工具
VisualC++6.0和Win32。
1.4应用平台
WindowsXP/Vista32位
2详细设计
2.1程序结构
程序的流程:
该程序首先定义了一个记录学生基本信息的结构体,和全局变量链表的头指针“*head”,自定义了13个函数,然后是主函数通过调用以上自定义函数来实现程序的功能。
这样做的好处是,在调用自定义函数时不必再对其申明。
主函数第一行首先在程序运行界面中央输出“欢迎进入学生管理”,接着是输出“按回车键进入”(在界面中央),以提醒用户进一步操作程序。
按回车键后程序执行创建链表函数(create()),这时出现界面需要用户输入三个学生的基本信息,按回车键后创建成功,同时进入while循环体。
该循环提以“system("cls")”开始,作用是在每次循环结束进入下一次循环时对上一次循环的运行结果进行清除,以保证本次循环的结果能清晰展示。
该循环第二行执行函数“printfmenu()”,输出当前链表内容。
接着进入菜单选择界面,此时需输入数字(0~8)进行菜单选择。
若输入‘8’,该循环结束;否则继续。
然后执行菜单选择函数,用户通过菜单上执行不同的操作调用不同的函数。
执行完菜单函数后,按回车键本次循环结束,并进入下一次循环。
循环结束后,又一次执行清屏程序,最后输出“谢谢使用,愿你开心度过每一天”字样,至此整个程序结束。
自定义函数:
一、显示菜单函数:
voidprintfmenu()。
用输出管理菜单:
1.显示
2.排序
3.插入
4.查找
5.删除
6.统计
7.存盘
8.读入
9.结束
二、链表输出函数:
voidprintfform()。
用来将已经创建链表或当前所建链表进行输出显示。
三、链表创建函数:
voidcreate()。
该函数用来创建一个动态链表,期间需要用户输入学生基本信息。
四、排序函数:
voidarrange()。
该函数用来对所创建的链表或当前存在的链表中的结构体按学号递增排序。
排序结束调用“链表输出函数”,将新产生的链表进行输出。
五、插入函数:
voidinsert().调用该函数时,由用户输入一个学生的信息,将产生一个新的结构体,并将其按学号插入当前链表中。
调用链表输出函数,将新链表输出。
六、查找函数:
voidfind()。
输入一个学号,将链表中该学生的信息输出。
若链表中无该学号,则输出“未找到”。
七、删除函数:
voiddelet()。
输入一个学号,将链表中该学号学生信息删除,并调用链表输出函数将删除后的链表输出。
若输入学号不存在,输出“未找到”。
八、按学生统计函数:
voidstudentcount()。
输入一个学号,计算该学号学生的总分和平均分并输出。
若学号不存在,输出
“未找到”。
九、按科目统计函数:
voidsubjectcount()。
输入一个科目序号(1.英语 2.数学 3.计算机),计算该科目的总分和平均并输出。
十、统计函数:
voidcount()。
当输入1,调用“按学生统计函数”;当输入2,调用“按科目统计函数”。
分别进行统计操作。
十一、存盘函数:
voidsave()。
将链表中的内容以文件的形式存放在磁盘中。
十二、读入函数:
voidread()。
将已经存盘的文件读入内存,进行管理。
十三、选择菜单函数:
voidmenu(chart)。
主函数输入实参变量‘t’,该函数通过选择判断调用以上函数来实现该程序的管理功能。
参数传递:
该程序包括主函数总共有14个函数,只有选择菜单函数是有参函数,其他均是无参函数。
选择菜单函数运用switch选择结构,形参的传递用来选择执行调用相应的菜单功能函数。
如从主函数输入‘1’,主函数调用该函数,并把‘1’传递给该函数,该函数则调用“排序函数”执行菜单中的排序操作。
2.2主要功能
程序功能:
1、该程序主要用来对数量较少的学生基本信息进行管理(初始学生数为三)。
2、显示输入的学生基本信息。
3、对学生按学号进行排序、,并将信息以链表的形式进行保存。
4、可通过插入操作增加所要处理的学生信息数量。
5、显示所要查找的学生的基本信息。
6、删除不必要的信息。
7、统计学生成绩的相关数据,总分和平均分。
8、将经过处理的信息存盘管理。
9、以文件的形式将以存盘信息读入内存进行管理。
原理和方法:
1、该程序的要通过对链表进行操作来实现管理。
2、用循环结构和指针对已存在链表输出显示,调用输出函数“printf”。
3、排序时先把链表中的学好数据存放在一位数组中,再用选择排序法对数组中的元素排序,最后用while循环结构把数组中的元素与结构体逐一配对,从而实现对链表的排序。
4、先用while找到插入位置,然后是链表的插入操作。
5、while循环执行查找操作。
6、while循环找到删除对象,链表的删除操作。
7、while循环找到操作对象,在执行相应操作。
8、文件的存储。
9、文件的读取。
2.3函数实现
函数主要运用了while、do。
。
。
while、for循环结构,还有选择排序法。
函数大多为无参类型,自函数之间有少量调用。
如排序、插入、删除、统计等函数都是较为简单的函数,只需根据医学知识稍加修改即可。
数据结构方面,主要事项是函数调用,主函数调用菜单函数,菜单函数又调用其它类型函数,其他自定义函数之间也有调用。
2.4开发日志
关于该程序的设计,首先根据题目的要求考虑实现该函数所需的函数。
考虑把自定义函数放在整个程序的前面,这样在主函数调用时就不必再对其进行申明。
比如必须的一些基本函数链表输出函数、链表创建函数、链表排序函数、查询函数、链表删除函数、统计函数等,先把这些基本函数建立起来之后,程序的整体结构。
考虑到程序的整体结构通过函数调用来实现较为方便,由此增加设计了一些函数,如链表输出函数、显示菜单函数、存盘函数、读入函数等。
函数的的创建过程实在是一个繁琐的工作,编译时常要去翻看课本去查找已经遗忘的C语言的相关语法知识,特别是一些细节上的设计,更不敢轻易放过。
如转义字符“\t”的使用回事程序界面更加美观整洁好看,期间也对结构体链表的知识作了较好的复习掌握。
在做到排序函数时突然忘了选择排序法的算法,于是通过查资料对其进行了重新的掌握,其中插入函数的算法较为复杂,通过分析发现,须先查找然后再插入,查找的算法编号之后,后面的统计、删除函数也就迎刃而解了。
调试的过程是最令人纠结的,觉得完好的程序却总是调不出来,经过复杂的心理脑力斗争最终发现却总是一些不该有的失误,而不是算法上问题。
调试的过程是用时最长的,同时也磨练了我的耐性,让我对频频出现的错误更加理智、更加淡定、更加耐心。
而且在调试的过程中也积累了一些常见的错误经验,对部分调试的错误能大体上感知其错误的原因及位置。
影响最深的是对排序函数的调试,指针数组的地址代码写错导致程序运行时不能读入,还有创建链表函数出现的问题,输入函数多打了几个“%lf”导致链表创建时出现乱码。
程序的整体结构设计参考了“C语言课程设计”一书,再次申明。
总之,程序的运行过程看是简单,作用也非常单一,但对于像我这样的智商不是很高的初学者而言,编程、调试过程是相当的艰辛与繁琐,其间个中滋味,汗水、辛酸只能把它埋在心底。
3程序调试及运行
3.1程序运行结果
程序开始运行界面
程序运行过程界面如下:
程序结束界面:
3.2程序使用说明
该程序较为简单,根据程序运行时的提示即可完成操作。
在第一次进行显示操作时,需按两次‘0’才能显示所建链表。
在完成一次菜单操作后,应按回车键返回主菜单。
3.3程序开发总结
大作业的编写,是一个对所学知识综合应用的过程,也是对所学知识掌握情况的检验过程,更是对所学知识系统复习的过程。
其间涉及除程序设计外多方面技能应用,能够很好训练一个人的整体思维能力,体现其综合素质。
同时在完成作业的过程中,也让我体验了当一个程序员的神奇感受。
当然我编的程序很简单,用途也很有限,其实就当前的程序来看根本没什么实际用途。
但是设计工作的过程还是让我体会到了其艰辛其难度,编完之后油然而生的小小成就感是相当美妙的。
在编程设计过程中遇到过很多问题和困难,也让我深刻认识到自己知识的欠缺,感受到自己离一个真正的程序设计人员的差距还是相当之远,自己还有很多只是要学习和掌握。
更重要的是过程激发了我对计算机编程的兴趣,虽然这门课程即将结束,当我想我对其的学习与热爱绝不会停止。
限于本人智商和时间的原因,该程序存在一定的缺陷和一些需要完善提高的地方,现在此处指出如下:
1、在链表的创建上,包含的信息量较少,仅有三个学生,其实据此方法可适当增加学生数量,以增强程序的实用性
。
2、再删除操作上,仅有对单个学生的删除功能,缺乏相应的全部删除功能,限于时间的原因未能增加。
3、在对学生信息处理上,功能较少,缺乏最高分最低分的统计以及对于程序的排序。
4、在统计功能的程序设计上,在选择完成一种统计操作后,程序即回到主菜单而不能回到统计界面继续进行统计操作,此不足之处未能改善。
当然通过对大作业的撰写,打字水平也有了较大的提高。
总之,完成大作业,无论是思想上、能力上还是知识上都有了较大的飞跃,各方面都受益匪浅。
4附件(源程序)
#include
#include
#include
structstudent
{
longnum;
charname[80];
doublescore[3];
structstudent*next;
};
structstudent*head;//定义全局变量head,各个函数中均可用
#defineLENsizeof(structstudent)
structstudent*stu;
voidprintfmenu()//将菜单列出函数
{
printf("\t\t\t\t0.显示\n");
printf("\t\t\t\t1.排序\n");
printf("\t\t\t\t2.插入\n");
printf("\t\t\t\t3.查找\n");
printf("\t\t\t\t4.删除\n");
printf("\t\t\t\t5.统计\n");
printf("\t\t\t\t6.存盘\n");
printf("\t\t\t\t7.读入\n");
printf("\t\t\t\t8.结束\n");
}
voidprintfform()//用于每次将链表列出
{
structstudent*p;
printf("\t学号\t姓名\t数学成绩\t英语成绩\t计算机成绩\n");
p=head;
if(head!
=NULL)
do
{
printf("\t%ld\t%s\t%.2f\t%.2f\t%.2f\n",p->num,p->name,p->score[0],p->score[1],p->score[2]);
p=p->next;
}
while(p!
=NULL);
elsereturn;
}
voidcreate()//创建三人构成的初始表
{
inti=0,j,k;
structstudent*p1,*p2;
charname1[3][80];
longnum1[3];
doublescore1[3][3];
head=p1=p2=(structstudent*)malloc(LEN);
printf("请输入3个所要处理的学生信息,包括学号、姓名,英语、数学、计算机的成绩\n");//赋予三个学生的信息
for(k=0;k<3;k++)
{
scanf("%ld%s",&num1[k],name1[k]);
for(j=0;j<3;j++)
scanf("%lf",&score1[k][j]);
}
while(i<3)//建立三个学生的链表
{
if(i==0)head=p1;
else
p2->next=p1;
p1->num=num1[i];
strcpy(p1->name,name1[i]);
for(j=0;j<3;j++)
p1->score[j]=score1[i][j];
p2=p1;
if(i==2)
p1->next=NULL;//链表结束
else
p1=(structstudent*)malloc(LEN);//开辟一个新的单元
i++;
}
}
voidarrange()//排序函数
{
voidprintfform();
structstudent*p1,*p2,*p[3];
longs[3];
p2=p1=head;inti,j,t,k;
for(i=0;i<3;i++)
{
s[i]=p1->num;
p1=p1->next;
}
for(i=0;i<3;i++)
{
k=i;
for(j=i+1;j<3;j++)
if(s[k]>s[j])k=j;
if(k!
=i)
{t=s[k];
s[k]=s[i];
s[i]=t;}
}
for(i=0;i<3;i++)
{
while(p2->num!
=s[i]&&p2!
=NULL)
p2=p2->next;
p[i]=p2;
p2=head;
}
head=p[0];p[0]->next=p[1];p[1]->next=p[2];p[2]->next=NULL;
printfform();
}
voidinsert()//插入函数
{
structstudent*p0,*p1,*p2;
chart;
printf("温馨提示:
需要进行排序后才可进行插入,输入9返回主菜单,按回车键继续\n");
t=getchar();
if(t=='9')return;
printf("请输入要插入的学号,姓名,数学成绩,英语成绩,计算机成绩\n");
stu=(structstudent*)malloc(LEN);
scanf("%ld%s%lf%lf%lf",&stu->num,stu->name,&stu->score[0],&stu->score[1],&stu->score[2]);
p0=stu;//p0指向要插入的节点
p1=head;//p1指向首节点
while((p0->num>p1->num)&&(p1->next!
=NULL))//找插入位置
{
p2=p1;
p1=p1->next;
}
if(p0->num<=p1->num)
{
if(head==p1)//插入到第一个节点前
head=p0;
else
p2->next=p0;
p0->next=p1;
}
else//插入到最后一个节点后
{
p1->next=p0;
p0->next=NULL;
}
printfform();//显示链表
}
voidfind()//查找函数
{
structstudent*p1;
longnum1;
p1=head;
printf("请输入要查找的学号");
scanf("%ld",&num1);
while(p1!
=NULL)
{
if(p1->num==num1)
{
printf("\t学号\t姓名\t数学成绩\t英语成绩\t计算机成绩\n");
printf("\t%ld\t%s\t%.2f\t%.2f\t%.2f\n",p1->num,p1->name,p1->score[0],p1->score[1],p1->score[2]);
break;
}
p1=p1->next;
}
if(p1==NULL)
printf("未找到");
}
voiddelet()//删除指定学号的函数
{
longnum;
structstudent*p1,*p2;
p1=head;
printf("请输入要删的学生的学号");
scanf("%d",&num);
while(num!
=p1->num&&p1->next!
=NULL)//p1指向的不是所要的节点,并且后面还有节点
{
p2=p1;
p1=p1->next;
}
if(num==p1->num)//找到了
{
if(p1==head)//对首节点特殊处理
head=p1->next;
else
p2->next=p1->next;
printfform();
}
else
printf("学号为%ld的同学未找到\n",num);
}
voidstudentcount()//按学生统计函数
{
doubleaver,zong;
structstudent*p1;
longnum;
printf("请输入学号");
scanf("%ld",&num);
p1=head;
while(p1!
=NULL)
{
if(p1->num==num)
{
zong=p1->score[0]+p1->score[1]+p1->score[2];
aver=zong/3;
printf("学号为%ld的总分=%.2f,平均分=%.2f",p1->num,zong,aver);
break;
}
p1=p1->next;
}
if(p1==NULL)
printf("未找到");
}
voidsubjectcount()//按科目统计函数
{
doubleaver,zong=0;
structstudent*p1;
inti,n=0;
printf("\t请选择科目(1~3)");
printf("\t1.数学");
printf("\t2.英语");
printf("\t3.计算机");
scanf("%d",&i);
p1=head;
while(p1!
=NULL)
{
zong=zong+p1->score[i-1];
n++;
p1=p1->next;
}
aver=zong/n;
printf("该科目的总分=%.2f,平均分=%.2f",zong,aver);
}
voidcount()//统计函数
{
intt;
printf("\t\t1.求学生总分平均分\n\t\t2.求科目总分平均分\n");
printf("请输入");
scanf("%d",&t);
switch(t)
{
case1:
studentcount();break;
case2:
subjectcount();break;
}
}
voidsave()//存盘函数
{
FILE*fp;
structstudent*p1;
p1=head;
if((fp=fopen("score.dat","wb"))==NULL)//不能打开时
{
printf("Cannotopenfile");
exit
(1);
}
while(p1!
=NULL)
{
fwrite(p1,LEN,1,fp);
p1=p1->next;
}
fclose(fp);
printf("已存到c:
//score.dat");
}
voidread()//读入函数
{
FILE*fp;
structstudent*p1,*p2;
charfilename[80];
p1=p2=(structstudent*)malloc(LEN);
printf("请输入要进行管理的文件名字:
");
scanf("%s",filename);
if((fp=fopen("score.dat","rb"))==NULL)//不能打开时
{
printf("Cannotopenfile");
return;
}
fread(p1,LEN,1,fp);//将文件的信息读给结构体
head=NULL;
while(!
feof(fp))//创建内容为文件内容的链表
{
if(head==NULL)
head=p1;
else
p2->next=p1;
p2=p1;
p1=(structstudent*)malloc(LEN);
fread(p1,LEN,1,fp);
}
p2->next=NULL;
printf("现在您可对%s进行操作了",filename);
}
voidmenu(chart)//选择菜单函数
{
switch(t)
{
case'0':
printfform();break;
case'1':
arrange();break;
case'2':
insert();break;
case'3':
find();break;
case'4':
delet();break;
case'5':
count
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 实验 作业 学生 成绩 管理