中南大学c语言课程设计学生成绩管理系统.docx
《中南大学c语言课程设计学生成绩管理系统.docx》由会员分享,可在线阅读,更多相关《中南大学c语言课程设计学生成绩管理系统.docx(31页珍藏版)》请在冰豆网上搜索。
中南大学c语言课程设计学生成绩管理系统
中南大学
C语言程序设计实践
实习报告
题目:
学生信息管理系统
学生姓名:
指导教师:
学院:
信息科学与工程学院
专业班级:
完成时间:
2012年6月29日
目录
1、系统功能介绍3
2、功能模块结构4
3、数据结构设计6
4、主要模块算法说明7
5、运行结果14
6、认识实习心得体会17
7、附录(程序源代码)19
8、参考文献30
一、系统功能介绍
1、录入学生基本信息:
学号、姓名、班级、性别、年龄、宿舍号码、电话号码等。
并且录入学生五门课程(数学、离散数学、C语言、物理、英语)的基本信息:
编号、学分、考试成绩、平时成绩、综合成绩、是否重修等;
2、计算每个学生各门功课的平均成绩,并按照平均成绩从高到低的次序输出学生信息;
3、修改所指定姓名学生的学生信息和课程基本信息;
4、删除所指定姓名学生的学生信息和课程基本信息;
5、插入某个学生的信息;
6、按学生姓名或按学生学好查询该学生各项的信息;
7、列出不及格的学生清单;
8、保存学生的信息;
9、读取学生的信息;
10、安全退出系统。
二、功能模块结构
1、主要结构模式图如下:
信息输出模块
信息插入模块
信息录入模块
信息删除模块
信息查询模块
信息修改模块
信息保存模块
输出不及格的学生信息
输出所有学生的信息
按姓名查询学生信息
按学号查询学生信息
2、模块总述:
整个程序结构比较清晰,由一个主函数和多个子函数组成。
主函数main()利用switch函数多种情况把各个子函数穿插使用在其中,构成了整个系统运行的主控模块。
整个程序中包含了信息录入、信息输出、信息修改、信息插入、信息查找、信息删除、信息保存和安全退出8大模块,分别蕴含了数据的输入、输出、插入、修改、查找、删除和保存功能,由各个子函数支撑其运行。
其中,信息的查找可以从姓名查找和学号查找两个方向进行。
而输出的信息也可分为处处全部学生信息和输出不及格学生信息两部分。
整个程序大致上由以上几大模块构成,下面就分别进行细致具体的说明。
3,功能模块描述:
(1)主控模块:
这是整个程序的灵魂部分,支撑着程序所有功能的选择和运行。
每个模块都是通过主控模块所指向的,系统通过主控模块进入其他模块的运行。
也就是说主控模块是整个系统的入口,然后由主控模块根据指令或特定条件通向相应的模块实现相应功能。
(2)信息录入模块:
录入学生信息,把所输入进去的学生信息以链表的形式建立,是其他模块的先决条件,否则其他模块会出现“这是一个空表”的提示。
(3)信息输出模块:
输出所有学生的信息,并且是按平均成绩的高低的顺序输出的。
也可以选择输出所有不及格的学生信息。
(4)信息插入模块:
在已输入了学生信息基础上插入其他学生的信息,即将数据插入到以建立的链表中。
(5)信息修改模块:
先找到要修改的学生的信息,然后构造一个修改界面,有供选择修改的各项信息。
修改之后退出该界面。
(6)信息查找模块:
可以根据学生姓名查找,也可以根据学生学号查找。
若表中没有该学生的信息会输出“没找到该生信息”提示说明。
若找到会输出该生信息。
(7)信息删除模块:
找到要删除的学生信息,并删除该生的全部信息。
删除信息后会给予提示。
(8)信息保存模块:
将学生信息保存在指定的文件中。
(9)安全退出系统
三、数据结构设计
整个程序是建立一个链表,然后通过对链表的一系列操作,来完成整个程序的运行。
定义函数来建立链表、输出链表,对链表进行插入操作、删除操作等等。
本程序使用了结构体类型的数据结构,来包括学生的各种信息,既有层次感,又保证了能够定义所有变量,清晰明朗,其中定义的变量为全局变量。
其他模块可直接使用已在此定义的变量。
structstudent
{
charnum[10];/*学号字符串变量长度为10*/
charname[15];/*姓名字符串变量长度为15*/
charClass[5];/*班级字符串变量长度为5*/
charsex[5];/*性别字符串变量长度为5*/
intage;/*年龄整型变量*/
charroomnum[3];/*宿舍号码字符串变量长度为3*/
chartel[12];/*电话字符串变量长度为12*/
charnum_[5][10];
/*各科编号字符串变量长度为10*/
(数学num_[0][10]、离散num_[1][10]、C语言num_[2][10]、物理num_[3][10]、英语num_[4][10])
floatxuefen[5];/*各科学分浮点型变量长度为5*/
floatscore[5][3];/*各科成绩浮点型变量*/
(考试成绩score[5][0],平时成绩[5][1],综合成绩[5][2])
charchongxiu[5][5];/*重修信息字符串变量*/
floataverage;/*总平均分浮点型变量*/
structstudent*next;/*定义一个指向结构体的指针*/
};
四、算法说明
1、main()主函数算法说明
主函数主要由switch函数构成。
根据不同的选择指令,调用不同的子函数。
1)主控模块:
运行后,首先出现一个学生信息管理系统主菜单,并输出各个功能的编号。
只要输入相应的功能号,就可以进入录入、输出、插入、修改、删除、保存、按姓名查找、按学号查找、列出不及格学生信息函数模块并可以安全退出系统。
进入各模块后,按提示操作也可以返回主菜单来。
2)信息录入模块:
调用函数structstudent*create(),进入录入模块。
按照指示输入学生的基本信息和课程信息,直到学号为!
结束输入。
此函数的目的是建立一个包含学生信息的链表,并把链表头作为函数值返回。
3)信息插入模块:
调用函数structstudent*insert(structstudent*head),进入插入模块。
按照指示插入学生的基本信息和课程信息到指定结点位置,并返回头结点地址。
4)信息删除模块:
调用structstudentDelete(structstudent*head)函数,然后输入要删除的学生姓名,若存在这个姓名,则删除。
若不存在,则提示不存在姓名为此的学生。
5)信息查找模块:
若想按学号查找则调用search1(structstudent*head)函数,输入要查找的学号,即可获得相应学生信息。
若想按姓名查找则调用search2(structstudent*head)函数,输入要查找的学号,即可获得相应学生信息。
如果输入的学号或姓名不存在,则系统会提示没有找到。
6)信息修改模块:
调用voidmotify(structstudent*head)函数。
输入要修改的学生姓名之后,进入修改菜单界面,按照所提示的功能号选择要修改的信息,修改完毕后返回修改子菜单。
若不存在此生姓名,则提示“没有姓名为此的学生”。
7)信息显示模块:
若要按平均成绩的高低输出所有学生的信息,则需要调用voidprint(structstudent*head)函数。
若要仅列出不及格学生的名单,则须调用viodlist(structstudent*head)函数。
8)信息保存模块:
调用voidsave(structstudent*head)函数。
输入一个要保存的文件名,即可保存到指定的文件名当中去,系统会有保存成功的提示。
9)安全退出系统:
通过使用do{}while(c!
=10)和switch(c)安全退出系统。
2、各模块子函数算法说明
每个模块有各自的功能,通过自身定义的子函数还完成相应的功能。
也就是说功能的实现是靠函数的调用完成的。
下面便具体的来介绍各个子函数的算法。
1)floatave(structstudent*head)
用来计算综合成绩和五科成绩的平均成绩的。
综合成绩的算法是平时城绩的30%+考试成绩的70%。
平均成绩的算法是各科成绩与各科学分的乘积总和再除以个课学分的总和。
在函数中,利用循环for(i=0;i<5;i++)通过p->score[i][2]=p->score[i][0]*0.7+p->score[i][1]*0.3;计算出综合成绩。
并由定义的变量各科成绩与各科学分的乘积总和s和学分总和m,用s/m求出。
2)structstudent*creat()
用来建立一个链表来包含学生基本信息和课程信息。
(1)设3个指针变量:
*head*p1*p2,用malloc函数开辟第一个节点,并使p1p2都指向它。
然后从键盘读入的数据给p1所指向的第一个结点,并调用floatave(structstudent*head)函数来求综合成绩和平均成绩。
先使head为空,建立第一个节点以后,head指向第一个结点。
若学号输入为!
,则链表的建立过程完成。
若p1->num不为!
,则把p1赋值给head,即开辟的新结点。
(2)利用循环for(i=0;;i++)来输入学生信息。
当学号为!
时,结束输入。
(3)每次循环都会开辟一个新的结点,令p1指向它,并调用floatave(structstudent*head)来求综合成绩和平均成绩。
若i=0,则指向表尾的p2=p1=head,所以形成一个空表。
若i≠0,p2=p1->next,使p2指向最后一个结点。
就这样一直循环下去,直到循环结束。
这样就建立了一个链表。
(4)free(p1);释放p1所占用的内存。
(5)return(head);返回头作为函数值的头指针。
3)structstudent*insert(structstudent*head)
用来插入某个学生信息到指定位置
(1)用malloc函数开辟一个新结点,令p1指向它,输入一个学生数据给p1所指向的结点,调用floatave(structstudent*head)函数来求综合成绩和平均成绩。
(2)按平均成绩的高低的顺序查找插入点,用已定义的结构体类型变量p2指向头指针,移动指针,p3=p2;p2=p2->next,直到找到插入点
(3)令p3->next=p1;p1->next=p2;将p1所指向的接点插入到相应的位置中。
4)structstudentDelete(structstudent*head)
用于找到指定姓名学生在链表中的位置,并删除该学生的信息。
(1)所输入的学生姓名要存放到数组name[15]中
(2)用p1指向要删除的结点,p2指向前一个结点,p1=head;p2=p1;p1=p1->next;利用循环while(strcmp(p->name,name)&&p->next!
=NULL),直到找到要删除的结点为止。
(3)若要删除的是头结点,则head=p1->next;若不是,则p2->next=p1->next;
(4)return(head);返回删除后链表表头地址。
5)voidsearch1(structstudent*head)
用来查找指定学号的学生信息并将其输出。
(1)所输入的学生学号要存放到数组num[10]中
(2)指针p1指向第一个结点,然后逐个检查移动指针,直至表尾。
p1=p1->next。
利用循环
while(strcmp(num,p1->num)&&p1!
=NULL)控制查找。
查找结束后,调用printf输出学生信息。
如果没有,则输出提示信息。
6)voidsearch2structstudent*head)
用来查找制定姓名的学生信息并将其输出。
算法如voidsearch1(structstudent*head)函数。
7)intcount(structstudent*head)
用函数的递归调用方法计算链表中已录入的学生数目,并将其作为函数值返回。
8)voidprint(structstudent*head)
用来输出量表中全部的学生信息。
(1)先按平均成绩从高到低的顺序将链表中的各结点排序,并依次存放到数组当中。
(2)调用intcount(structstudent*head)函数计算学生的数目m
(3)利用循环for(i=0;i9)voidmodify(structstudent*head)
用来修改指定姓名的学生的指定信息。
(1)所输入的学生姓名要存放到数组name[15]中
(2)令p1=head;用循环语句
while(strcmp(name,p1->name)&&p1->next!
=NULL)
p1=p1->next;找到要修改的结点。
(3)用switch函数选择要修改的信息选项,用Do{}while(i!
=13);实现多次修改。
10)voidlist(structstudent*head)
用来列出不及格学生的名单。
(1)定义结构体指针变量p=head;利用循环while(p!
=NULL)循环语句实现对不及格学生的判断和输出功能。
利用if语句判断,令p=p->next移动指针。
(2)定义整型变量i,来判断是有存在不及格的学生。
11)voidsave(structstudent*head)
用来保存以建立的链表文件。
(1)定义一个文件指针fp,一个结构体指针p,一个字符串数组outfile[15]用来存放文件名。
调用fopen函数,把地址赋给文件指针fp。
若fp=NULL,则返回。
(2)若fp≠NULL,则将数据保存到指定文件中,p=head。
(3)利用循环语句
while(p!
=NULL)
{fwrite(p,sizeof(structstudent),1,fp);
p=p->next;}多次调用fwrite()函数,直至写入所有信息。
五、运行结果
1、主菜单界面:
2、输入数据:
(在学号处输入!
安全退出输出模块)
3、插入信息:
4、删除数据:
5、显示学生信息:
6、修改学生信息:
7、列出不及格学生信息:
8、保存界面显示:
9、安全退出系统界面显示:
六、认识实习心得体会
在看到认识实习任务计划书的时候,没想到自己是真的可以完成这样一个繁琐的程序设计的。
认真的权衡了一下各个任务的侧重点和考察方向,我决定要设计一个小型的学生信息管理系统,权当是对自己所掌握的链表以及相关知识的一种检测。
然而在最初的几日,虽然满脑子都是链表,数组,但都是些独立的程序,理不出什么思路。
不过,当我把系统所需要的各项功能定义为一个个函数,整个系统的基本脉络就清晰了。
虽然确定了主菜单为主函数并运用switch函数来贯穿整个系统,可在每个功能模块的设计上还是遇到了很多的问题。
例如:
在输出不及格学生名单的list函数就出了一点问题。
最开始一直以为要输出所有要重修的人,所以想要检查每个人是否需要重修,冥思苦想好久都不知道该怎么检查每个同学的五个科目的重修情况。
后来经过同学提点,才发现可以直接比较每科科目成绩,如果低于六十分就是不及格,就把那个学生的成绩输出。
于是问题迎刃而解。
这个只是算法上的失误,当然也有语法上的错误。
进过多次调试和同学的指正后得到了整个程序的雏形。
由于是中文版本的,所以就在win-TC上运行调试,还有用中文DOS运行。
虽然很是麻烦,但总感觉中文的系统要比拼音和英文亲切的多。
在完成整个程序的时候,心里的喜悦是满溢于面的。
其实世界上真的没有什么不可能的事,我也绝对不会想到自己会完成这样一个系统的编译。
说是系统,也是最简单最浅显的那种,退去其貌似庞大的外壳,不过都是函数组成的,由链表组成连接的数据输入,输出,修改,整理,查找,删除。
而且像链表的建立,输出还有删除和插入,是完全可以在书上找到例子的。
这又一定程度上降低了编译过程的难度。
其实书本上的知识都是死的,只有像这样的,把书本上的知识,经过加工和调试应用到实践中,才发挥出知识的真正作用。
经过这两周的实习,我很清楚的认识到自己所学的东西是多么的浅显,粗略掌握的整个知识结构脆弱的不堪一击,一遇到问题,就会手忙脚乱,不能偶冷静的去分析问题,也不能好好的把知识活学活用。
不过,这次的实习锻炼了我独立思考、独立解决问题的能力,并且加深了C语言知识,而且更深层次的理解了各知识点的原理和运用。
现在的我,有着更清晰的思路,对算法的说明更加清晰明确,这都要感谢老师的指导和同学们的帮助,和这次虽然辛苦却受益颇多的实习。
很感谢这次的课程设计,它使我更加深刻地体会到多看专业书的重要性,只有掌握了一定量的专业知识才能得心应手地解决诸多问题;另外,做任何事都要有耐心,不要一遇到困难就退缩;在学习和工作中要时刻谨记“团结”二字,它好比通向成功的铺路石,不可或缺。
总之,这次的实习,我受益了很多,是我人生当中一次难忘的一次经历。
相信在以后的日子里,我会时常提醒自己,没有不可能完成的事,只要够认真,够细心,够有耐性。
只是一定要运用到实践中去才能发挥最大的价值。
七、附录(程序源代码)
#include
#include
#include
#defineLENsizeof(structstudent)
#defineN5
voidf(void)
{floata;
scanf("%f",&a);}
structstudent
{charnum[10];
charname[15];
charClass[5];
charsex[5];
intage;
charroomnum[3];
chartel[12];
charnum_[5][10];
floatscore[5][3];
floatxuefen[5];
charchongxiu[5][5];
floataverage;
structstudent*next;
};floatave(structstudent*p)
{inti;
floatm,s,ave;
{for(i=0;i<5;i++)
{m=p->xuefen[i];
p->score[i][2]=p->score[i][0]*0.7+p->score[i][1]*0.3;
s=p->score[i][2]*p->xuefen[i];}
}
ave=(float)s/m;
returnave;
}
structstudent*create()
{inti;
structstudent*head,*p1,*p2;
head=NULL;
for(i=0;;i++)
{p1=(structstudent*)malloc(LEN);
printf("请输入学生基本信息:
\n");
printf("学号:
\n");
scanf("%s",&p1->num);
if(strcmp(p1->num,"!
")==0)break;
printf("姓名:
\n");
scanf("%s",&p1->name);
printf("班级:
\n");
scanf("%s",&p1->Class);
printf("性别:
\n");
scanf("%s",&p1->sex);
printf("年龄:
\n");
scanf("%d",&p1->age);
printf("宿舍号码:
\n");
scanf("%s",&p1->roomnum);
printf("电话:
\n");
scanf("%s",&p1->tel);
printf("选修课信息:
\n");
printf("数学课信息:
\n");
printf("编号:
\n");
scanf("%s",&p1->num_[0]);
printf("学分:
\n");
scanf("%f",&p1->xuefen[0]);
printf("考试成绩:
\n");
scanf("%f",&p1->score[0][0]);
printf("平时成绩:
\n");
scanf("%f",&p1->score[0][1]);
printf("是否重修?
\n");
scanf("%s",p1->chongxiu[0]);
printf("离散数学课信息:
\n");
printf("编号:
\n");
scanf("%s",&p1->num_[1]);
printf("学分:
\n");
scanf("%f",&p1->xuefen[1]);
printf("考试成绩:
\n");
scanf("%f",&p1->score[1][0]);
printf("平时成绩:
\n");
scanf("%f",&p1->score[1][1]);
printf("是否重修?
\n");
scanf("%s",p1->chongxiu[1]);
printf("C语言课信息:
\n");
printf("编号:
\n");
scanf("%s",&p1->num_[2]);
printf("学分:
\n");
scanf("%f",&p1->xuefen[2]);
printf("考试成绩:
\n");
scanf("%f",&p1->score[2][0]);
printf("平时成绩:
\n");
scanf("%f",&p1->score[2][1]);
printf("是否重修?
\n");
scanf("%s",p1->chongxiu[2]);
printf("物理课信息:
\n");
printf("编号:
\n");
scanf("%s",&p1->num_[3]);
printf("学分:
\n");
scanf("%f",&p1->xuefen[3]);
printf("考试成绩:
\n");
scanf("%f",&p1->score[3][0]);
printf("平时成绩:
\n");
scanf("%f",&p1->score[3][1]);
printf("是否重修?
\n");
scanf("%s",p1->chongxiu[3]);
printf("英语课信息:
\n");
printf("编号:
\n");
scanf("%s",&p1->num_[4]);
printf("学分:
\n");
scanf("%f",&p1->xuefen[4]);
printf("考试成绩:
\n");
scanf("%f",&p1->score[4][0]);
printf("平时成绩:
\n");
scanf("%f",&p1->score[4][1]);
printf("