1、中国地质大学本科生课程论文封面课程名称C语言课程设计教师姓名本科生姓名本科生学号20111000013本科生专业安全工程所在院系类别:本科生日期:2013-1-122课程设计评语对课程论文的评语平时成绩:课程论文成绩:总成绩:评阅人签名:注:1无评阅人签名成绩无效;2、必须用钢笔或圆珠笔批阅,用铅笔阅卷无效;3、如有平时成绩,必须在上面评分表中标出,并计算入总成绩。目录课程设计评语2目录31.课程论文题目42.程序设计思路43.
2、功能模块图54.数据结构设计75.算法设计86.程序代码137.程序运行结果208.编程中遇到的困难及解决方法239.总结心得及良好建议2410.致谢2541.课程论文题目学生成绩管理系统:【要求】设计“学生成绩管理系统”,实现学生成绩的录入、显示、查找、添加、保存以及成绩排序等功能模块。要求功能选择用菜单实现,数据输入和结果输出要求用文件存放。原始数据文件格式(具体数据自行编写):学号姓名英语c语言高等数学平均成绩1张三758580
3、802李四............2.程序设计思路【思考】(1)需求分析由于要录入、读取、保存学生成绩信息,因而要实现文件的输入输出功能;要求用户可以查询各个学生的成绩,并且可以添加学生成绩信息等,因而要提供查找和添加功能;另外,还应该提供键盘式选择菜单以实现功能选择。(2)总体设计可以将这个系统的设计分为数据输入、数据显示、数据查找、成绩排序、保存数据、读取数据、数据插入7个模块。(3)数据结构把学生的学号、姓名、科目成绩、平均成绩作为结构体成员,存放若干学生信息用结构体数组。53.功能模块图【输入学生数
9、structstudent:.-u[])iinti,k,:;structStudenttenp;For(i=B;i
16、为假则终止函数。5.算法设计(1)总体设计把学生的学号、姓名、科目成绩、平均成绩作为结构体成员,存放若干个学生的信息用结构体数组。将要实现的功能分为一个一个的函数模块,需实现哪个供的语句时就调用该功能语句。而要实现菜单式的功能选择又需要while中嵌套swith语句,即调用完一个函数后进行while判断,while中的条件控制语句如果为真,则执行功能选项,然后进行swith判断,符合case几的选项就调用相应的函数,然后再进行while判断,直到不符合条件是跳出循环,结束函数。这样就实现了函数的菜单式功能选择并得到相应的结果。(2)各个
18、下:voidinput(structStudentsdu[]){inti;printf("请录入学生信息:学号姓名英语c语言高等数学(数据之间用空格隔开):\n");for(i=0;i 19、}}(4)学生信息输出模块具体算法输出学生数据跟输入学生信息类似,用for循环遍历结构体中的每一个成员,设置输出格式,就能完成每一个学生信息的输出显示功能。代码如下:voidprint(structStudentsdu[]){inti;for(i=0;i 20、(5)学生信息查询模块具体算法查询原理是,根据学生的学号查询。定义一个变量接收要查询学生的学号,然后用for循环中嵌套if语句遍历查找结构体成员中的学号成员,如果查到相等的学号,执行输出语句,输出该学生的所有信息,最后执行break终止循环。如果未找到匹配的学号则N值>=N,此时执行提示语句,“无该学生信息!”最后结束循环到功能选择菜单。代码如下:voidsearch(structStudentsdu[]){inti,num_get;printf("请输入要查询的学生的学号:");scanf("%d&quo 21、t;,&num_get);for(i=0;i 22、行排序,排序成功后再调用输出函数,实现学生平均成成绩由高到低的信息的输出。代码如下:voidorder(structStudentsdu[]){inti,k,j;structStudenttemp;for(i=0;i 23、构体指针变量fp1,然后将文件指向打开文件的信息区,设置打开文件方式为写方式,如果打开文件失败则执行提示语句,如果打开文件成功执行fprintf函数,将结构体成员中的信息按指定的格式输出到fp1指向的文件中,关闭文件,然后返回到功能选项菜单。代码如下:voidsave(){FILE*fp1;inti;if((fp1=fopen("student.txt","w"))==NULL){printf("cannotopenfile\n");return;}fprin 24、tf(fp1,"%s",tips);for(i=0;i 25、行下面的读入数据操作,读入完成关闭文件,然后后再调用输出函数显示读取的数据,最后返回到菜单功能选择。代码如下:voidread(){FILE*fp2;inti;if((fp2=fopen("student.txt","r"))==NULL){printf("cannotopenthisfile!\n");return0;}for(i=0;tips[i]!=0;i++)fscanf(fp2,"%c",&tips[i]);for(i=0;!feof 26、(fp2);i++){fscanf(fp2,"%d%s%f%f%f%f",&sdu[i].num,&sdu[i].name,&sdu[i].Eng,&sdu[i].c,&sdu[i].math,&sdu[i].aver);}fclose(fp2);}(8)插入学生信息模块具体算法插入学生信息是在原来设定的的N个学生基础上又增加学生的信息,原理为插入的第一个学生是结构体数组的第N个元素。定义整型变量,可实现选择添加几个学生的信息,用for循环遍历输入,信息输 27、入完成后执行提示语句,即完成了学生信息的插入功能。代码如下:voidinsert(){inti,j,temp;printf("请输入插入的学生个数:");scanf("%d",&temp);N=N+temp;for(j=0,i=(N-temp);i 28、-temp+j].name,&sdu[N-temp+j].Eng,&sdu[N-temp+j].c,&sdu[N-temp+j].math);sdu[N-temp+j].aver=(sdu[N-temp+j].Eng+sdu[N-temp+j].c+sdu[N-temp+j].math)/3;}}注意:为了节省篇幅程序模块中的大多注释都已删除,如有不明白的地方可参考源程序中的注释!6.程序代码#include 32、t;);printf("**\n");printf("**\n");printf("**\n");printf("*6)*\n");printf("**\n");printf("*输入学生数据(请输入1)查询(请输入3)将学生信息保存到文件中(请输入5)输出学生信息(请输入2)成绩排序(请输入4)从文件中读取学生信息(请输入 33、17插入学生信息(请输入7)printf(*******\n");*\n");printf("**\n");printf("**\n");printf("**\n");H******************************************************************##//菜单选项变量初始化 34、为1,menu=1;目的是进入while下面的switch语句选择##while(menu>=1&&menu<=7)//该系统要实现七个功能,每##一个数字代表一个函数模块{printf("请输入功能选项:");scanf("%d",&menu);switch(menu){case1:input(sdu);息函数break;case2:print(sdu);函数break;c 35、ase3:search(sdu);息函数break;case4:order(sdu);print(sdu);绩排序函数和输出学生信息函数break;case5:save();息函数break;case6:read();息函数和输出学生信息函数print(sdu);break;case7:insert();息函数break;default:printf("error!\n");该语句,终止//当选择1时,调用输入学生信//当选择2时,调用输出学生信息//当选择3时,调用查 36、询学生信//当选择4时,调用学生平均成//当选择5时,调用保存学生信//当选择6时,调用读取学生信//当选择7时,调用插入学生信//当选择不在1--7范围内时,执行switch语句,然后跳出循环,函数结束break;}1920return0;}/*定义输入学生信 37、息模块*/voidinput(structStudentsdu[]){inti;printf(****\n");printf("请录入学生信息:学号姓名英语c语言高等数学(数据之间用空格隔开)\n");//该语句为提示性语句for(i=0;i 38、i].c,&sdu[i].math);sdu[i].aver=(sdu[i].Eng+sdu[i].c+sdu[i].math)/3;printf(H********************************入完成#**\n");*****************************}//输入完学生信息后的提示语句,以便进入下一个功能选项/*定义输出学生信息模块*/voidprint(structStudentsdu[]){inti;printf(H******************* 39、*****************************************printf("学号姓名英语c语言输出结果高等数学平均成绩\n");for(i=0;i 40、8.1f%10.1为输出格式,定义数据的域宽}/*定义查询学生信息模块*/voidsearch(structStudentsdu[]){num_get;inti,//定义num_get整型变量,用来接收需查询的学生的学号printf("请输入要查询的学生的学号:");scanf("%d",&num_get);for(i=0;i 41、的信息,最后break结束循环{21#printf(****************************\n");printf("学号姓名英语所查学生信息为c语言高等数学平均成绩\n");printf("%3d%8s%8.1f%8.1f%8.1f%10.1f\n",sdu[i].num,sdu[i].name,#//当i的值>=N时则表示未查找到相应的//用选择排序,根据学生的平均成 42、绩从高sdu[i].Eng,sdu[i].c,sdu[i].math,sdu[i].aver);break;}if(i>=N)printf("无该学生信息!\n");学生的学号,则执行提示该语句}/*定义学生成绩排序模块*/voidorder(structStudentsdu[]){inti,k,j;structStudenttemp;for(i=0;i 43、lt;sdu[j].aver)k=j;}if(k!=i){temp=sdu[i];sdu[i]=sdu[k];sdu[k]=temp;printf(**************************\n");成绩从高到低//排序成功后的提示性语句排序结果为22#//定义文件指针变量fp1//将fp1指向所打开的student.txt//如果文件打开失败则提示该语//将主函数前的提示性语句保for(i=0;i 44、uot;%3d%8s%8.1f%8.1f%8.1f%10.1f\n",sdu[i].num,sdu[i].name,/*定义保存学生信息模块*/voidsave(){FILE*fp1;inti;if((fp1=fopen("student.txt","w"))==NULL)文件的信息区,打开文件方式为写{printf("cannotopenfile\n");句return;}fprintf(fp1,"%s", 45、tips);存到打开的文件中#//将变量中的学生信息sdu[i].Eng,sdu[i].c,sdu[i].math,sdu[i].aver);按预定的格式存入到打开的文件中fclose(fp1);printf(H*********************************************\n"}性语句//保存成功后关闭文件已将学生的信息保存到文件中//信息保存成功的提示##/*读取保存在文件中的学生信息模块*/voidread(){FILE*fp2; 46、inti;//将fp2指针指向文件的信息区,if((fp2=fopen("student.txt","r"))==NULL)打开方式为读#printf("cannotopenthisfile!\n");return0;//打开文件失败的提示语句23}for(i=0;tips[i]!=0;i++)//遍历从保存的文件中读取文件中的提示语句fscanf(fp2,"%c",&tips[i]);//读取该提示信息是为了能够顺利读 47、取存入的学生信息,实际输出时并未输出该提示语句for(i=0;!feof(fp2);i++){fscanf(fp2,"%d%s%f%f%f%f",&sdu[i].num,&sdu[i].name,&sdu[i].Eng,&sdu[i].c,&sdu[i].math,&sdu[i].aver);}//遍历读取保存在文件中的学生信息fclose(fp2);//读取成功后关闭文件printf(**************************\n"); 48、从文件中读取的数据//读取成功后的提示语句/*定义插入学生信息模块*/voidinsert(){inti,j,temp;态选择插入学生个数printf("请输入插入的学生个数:");scanf("%d",&temp);//定义temp整型变量,目的是动//输入需插入的学生的个数printf(H*************************************************************************\n"); 49、#printf("请录入学生信息:学号姓名英语c语言高等数学(数据之间用空格隔开)\n");N=N+temp;//插入后的学生个数for(j=0,i=(N-temp);i 50、+j].c,&sdu[N-temp+j].math);sdu[N-temp+j].aver=(sdu[N-temp+j].Eng+sdu[N-temp+j].c+sdu[N-temp+j].math)/3;printf(H*******************************插入成功*******************************\n");//插入成功后的提示语句#7.程序运行结果菜单展示:*C:\U^ers\Admini5tratoADesktop\a\Debug\c.exe24 51、#输入学生数据(请输入1)输出学生信息(请输入;:)iW查询〔请输入3)成绩排序(请输入初##将学生信息保存到文件中(请输入5)从文件中读取学生信息(请输人G:##插入学生信息(请输入7)请输入功能选项,1.输入功能展示:2.显示功能展示:请输入功能选项:2~UJVHT输岀结果为I学号姓铳英语G语百高等数学平均成绩■2^)10/卿卫85.0盹”3 56、88.编程中遇到的困难及解决方法1)总体设计中遇到的问题是,知道每一个功能都能通过一个独立的函数来实现,知道学生数据用结构体形式存储,但是一次只能一开始遇到的瓶颈是函数没办法返回到菜单选项,一次只能执行一个函数。程序完成之初,先完成的是每一个独立功能函数,其中的大多函数模块来自于《c程序设计》教材和《c语言课程设计及学习指导》。最后完成的是菜单功能循环选择功能,即while循环语句的运用。这个思想来自于《c语言课程设计及学习指导》中的工资信息管理实现思路。2)本程序有7个功能模块函数,其中的输入功能、输出显示功能、排序功能、数据 57、保存到文件功能、从保存的文件中读取数据功能很好实现,因为前面讲的两本书中都有模块!插入学生信息功能和查询功能难度稍大一点。下面就叙述一下当时我是怎样思考这个问题的。3)插入功能。教材上的例题是将结构体数组的长度在函数的最前面宏定义为一个常数,当需要改变结构数组长度时,只需将N定义为另一个常数即可,但是假如这样做的话就不能实现插入功能了。因为一是在函数运行过程中是不能修改N的值的,关闭程序修改N常数,然后从新输入数据。这样虽然增加了输入学生的个数,但是,在函数运行时不能实现动态的添加。我就想,数组的长度可以用宏定义的方式定义,而可以定义一个长度较大 58、的常数,比如100。解决了这个问题,需要一个常量来控制输入学生的个数,因为我们不可能真的输入100个学生的信息,这时我就想到了,用一个全局变量,这个全局变量既能控制学生的一次输入个数,又能动态的添加学生信息,一次可以添加想要添加的学生个数。因为全局变量在函数的运行期间始终存在,值可变,而且可以被其他的函数所引用,因此实现了这个功能。一开始未考虑到用全局变量的原因是,因为全局变量在函数的运行过程中始终存在,在各个函数中的重复运用是容易造成错误,应当尽量少用全局变量的想法!通过这个例子使我了解了变量的灵活运用(4)查找功能。查找功能是教材上没有 59、的。因此在学这个功能模块的时候遇到了一些困难。一开始的思路是,要实现查找必须要有一个条件语句,即满足什么条件的时候执行输出查找的那个学生。是定义一个变量k来接收循环到i是的值,然后用k为下标输出该学生的个成员信息。想到这儿我就开始写该模块。首先想到的是以什么为查找依据。而这个成绩管理系统中只有两个位依据,一是学号,二是姓名。如果姓名为依据,可能存在同名这样的查找可能不准确,再者是因为用姓名为依据要用到strcmp字符串比较函数,处于这两原因舍弃了姓名查找,而选择学号查找。每一个学生的学号唯一,这样查询出来的结果准确。以学号为查找依据后就开始着手写。 60、首先查找必须得用到一个循环语句遍历寻找,满足条件时就输出该学生的成绩。因为找到了学生的信息后循环就没有必要再执行,用break终止循环,这样可以提高函数的执行效率。这些是解决了查找存在有该学生信息的学生信息,但是假如查询的是一个不存在的学号,程序没有任何响应,这会给人一种根本没有调用查找函数感觉。因此需加入一个提示语句。当时我添加了else语句,但是这样的后果是,在没找到的情况下,循环了几次提示语句就输出了几次,这显然不是想要的结果。突然我想到了教材中的一个解决相同问题是办法,就是添加一个if(i>=n)时执行什么,因此通过添加这个语句,这个查询功能的