《C语言程序设计II》综合性实验资料.docx
- 文档编号:23607717
- 上传时间:2023-05-19
- 格式:DOCX
- 页数:19
- 大小:153.33KB
《C语言程序设计II》综合性实验资料.docx
《《C语言程序设计II》综合性实验资料.docx》由会员分享,可在线阅读,更多相关《《C语言程序设计II》综合性实验资料.docx(19页珍藏版)》请在冰豆网上搜索。
《C语言程序设计II》综合性实验资料
综合性实验:
小学生成绩管理系统
实验学时:
4学时
涉及的知识点:
分支语句、循环、分类统计、结构体、函数、文件操读写,记录的排序、增删改查等操作
一、实验目的
综合应用分支语句、循环、结构体、函数、文件操读写、排序等知识,实现一个小学生成绩管理系统的程序。
(1)掌握结构体的类型声明、变量定义与初始化;
(2)掌握函数的声明、定义和调用,能够正确理解、使用指针作参数的函数;
(3)理解模块化程序设计的要点:
把一个较大的程序模块划分为若干小模块,小模块包含一个或多个函数,每个函数实现一个特定的功能,main函数起主控作用;
(4)熟悉控制台环境下菜单设计的基本思路,并能通过菜单的选择调用相应函数模块;
(5)掌握文本文件的打开、读取、写入、关闭等操作;
(6)熟悉记录的排序、增删改查操作的基本思路。
二、实验内容
某小学要求在学生考试结束后,对考试成绩进行简单的处理和统计。
功能包括:
成绩的输入、删除、修改、查找、排序、统计、保存到文件等。
学生的考试科目有:
语文、数学和外语三科。
学生基本信息包含:
学号、姓名两项。
学生总人数不超过1000人。
一个学生的所有信息(包括基本信息、成绩等)为一条记录。
主要功能列举如下:
(1)输入若干条学生成绩记录(包括学号、姓名、各科成绩)。
(2)显示所有记录。
(3)计算每个学生的总分。
(5)按姓名查找并显示相应的记录。
(6)按学号查找并删除相应的记录。
(7)输出各个科目的统计信息(最高分、平均分、及格率、优秀率等)。
(8)将数据保存到文本文件中。
(9)从文本文件中读取数据。
三、实验器材设备
安装了WindowsXP(或其他版本的Windows操作系统)和VS2010(或以上版本的VisuslStudio版本)的PC机一台。
四、实验要求
(1)主要的数据存储方式
该程序主要处理学生成绩。
学生成绩数据比较多,而每个学生的信息都具有相同的结构,这种情况最适宜采用结构体数组进行存储。
因为已经知道学生人数不超过1000人,所以只需要定义元素个数为1000的结构体数组即可。
为了适当增加灵活性,可以将学生人数的最大值定义为一个常数。
如果学生人数不能预测,则需要利用动态内存分配技术和链表等,复杂度会增加。
结构体定义:
注意包含学生基本信息、三科成绩,另外还要一个总分字段。
#defineMAX_STUDENT_COUNT1000
typedefstruct/*定义结构体数组*/
{
intnum;/*学号*/
charname[20];/*姓名*/
doublechi;/*语文*/
doublemath;/*数学*/
doubleeng;/*英语*/
doubletotal;/*总分*/
}Student;
StudentStud[MAX_STUDENT_COUNT];/*结构体数组变量*/
intStudent_Count;/*学生记录数*/
由于整个程序功能主要就是围绕这个结构体数组进行,为了减少参数的传递,可以将变量定义为全局变量。
(2)主菜单设计
程序的功能比较多,为了方便用户操作,常用的方式是在进入程序后提供一个主菜单(列出程序提供的功能),让用户可以通过直观的方式选择要执行的功能。
主菜单的设计要注意,应该包含所有的系统功能,并且有快捷键执行相应的菜单。
根据本程序的功能,可以设计如图1所示的主菜单:
图1系统主菜单示图
用户在执行完一个功能后,往往还要继续执行另一个功能。
此时需要循环地显示主菜单,输入用户的选择,并执行相应的功能。
一般使用如下的循环实现:
while(choice!
='q')
{
//显示主菜单
choice=getchar();
switch(choice)
{
case'1':
//执行功能1
break;
case'2':
//执行功能2
break;
...
case'0':
}
}
设计好菜单显示的内容之后,只需要直接显示出来即可。
(3)数据的显示
在程序的多处地方都需要显示数据,一些地方需要显示多条记录,而另外一些地方则需要显示单条记录。
该程序对多条记录和单条记录均采用统一的输出格式,方便了程序的编写。
显示方法为首先显示统一的表头,然后依次显示每一条记录的内容。
(4)文本文件格式的设计
程序需要输出数据到文本文件中,并且要求还能够从文本文件中读取数据。
如果设计不合理,会导致生成的数据文件无法正确读取出来等问题。
为了方便数据的写入和读取,这里采用文本文件格式。
格式如下:
<记录总数>
<学号>
<姓名>
<语文>,<数学>,<英语>
...
<学号>
<姓名>
<语文>,<数学>,<英语>
例如:
一个数据文件内容
3
100
Zhang3
98,67,53
101
Li4
65,92,84
102
Wang5
93,84,97
文本数据文件的生成和读取都按照这一格式来进行,在文本文件的最开始处放置记录的个数,是为了方便数据的读取。
(5)使用fflush()函数清空文件缓冲区
程序经常需要从键盘读入一个字符的命令。
如果在getchar()之前,输入缓冲区中还有一些未被读取的字符,会导致getchar()直接读取用户以前输入的尚未被读取的字符,甚至包括用户输入的回车符。
因此,在需要获取用户最新输入的字符时,需要首先清空标准输入文件(stdin,一般对应输入的键盘)输入缓冲区的内容。
清空键盘输入缓冲区的方法是调用fflush(stdin)。
stdin是预先打开的标准输入文件的文件指针。
(6)程序主要函数原型和说明
1)voiddisplay_menu()
功能:
显示系统的主菜单。
2)voiddisplay_header()
功能:
显示记录的标题。
3)voiddisplay_a_record(Student*pstud)
功能:
显示一条记录的记录体。
通过结构体指针传递参数,可以减少参数传递的开销。
4)voiddisplay_all_record()
功能:
显示全局变量中的所有记录。
实现主菜单中“显示所有记录”的功能。
5)Studentinput_a_record()
功能:
输入单个学生的记录,并返回该记录。
6)voidinput_record()
功能:
添加记录。
函数会循环提示用户输入学生信息,并逐条记录添加到全局结构体数组变量Stud中。
实现主菜单中“添加记录”的功能。
7)voidcalc_total()
功能:
计算所有记录的总分。
总分为三科成绩的和。
在显示记录和排序之前,都需要计算总分。
8)voidsort_by_num()
功能:
按学号排序。
将学生记录按照学号由小到大的顺序排列。
9)voidsort_by_total()
功能:
按总分排序,将学生记录按照总分由大到小的顺序排列。
10)intDelete_record_by_num(intnum)
功能:
在学生记录中删除学号为num的记录。
11)voidDelete_a_record()
功能:
删除记录。
首先输入要删除的学生的学号,然后删除该学号对应的学生记录。
对应主菜单“删除记录”的功能。
12)Student*query_a_record_by_name(char*name)
功能:
在学生记录数组中查找指定姓名的学生记录。
如果找到,则返回该记录的指针,否则返回空指针NULL。
13)voidquery_a_record()
功能:
输入一个学生的姓名,找到并显示匹配的学生记录。
14)voidStatistic()
功能:
计算并输出所有学生记录的统计值,主要包括各科平均分和最高分。
15)voidread_textfile()
功能:
从文本文件中输入学生记录。
16)voidwrite_textfile()
功能:
将所有记录输出到文本文件中。
五、实验步骤
(1)新建一个项目:
VC++/win32控制台程序,创建一个C++项目,再创建C程序;
(2)将下列代码复制到C程序中。
根据要求,填写所缺代码,回答相关问题:
//只包含“添加记录”和“显示记录”两项功能的程序
#include
#include
#include
#include
typedefstruct/*定义结构体数组*/
{
intnum;//学号
charname[20];//姓名
doublechi;//语文
doublemath;//数学
doubleeng;//英语
doubletotal;//总分
}Student;
//主要的全局变量
StudentStud[MAX_STUDENT_COUNT];//结构体数组变量*/
intStudent_Count;//学生记录的个数*/
voiddisplay_menu()
{
printf("\n\n\n");
printf("*************学生成绩管理系统*******\n");
printf("1.添加记录\n");
printf("2.显示所有记录\n");
printf("3.按学号排序\n");
printf("4.按总分排序\n");
printf("5.删除记录\n");
printf("6.成绩查询\n");
printf("7.成绩统计\n");
printf("8.从文本文件中读取成绩\n");
printf("9.保存成绩到文本文件中\n");
printf("0.退出系统\n");
printf("*************************************\n");
printf("请选择要执行的功能(0-9):
");
}
voiddisplay_header()
{
printf("学号姓名语文数学英语总分\n");
}
voiddisplay_a_record(Student*pstud)//输出单个记录
{
printf("%5d%-20s%5.1f%5.1f%5.1f%5.1f\n",
pstud->num,
pstud->name,
pstud->chi,
pstud->math,
pstud->eng,
pstud->total);
}
voiddisplay_all_record()/*显示所有记录*/
{
inti;
display_header();
for(i=0;i { display_a_record(&Stud[i]); } } Studentinput_a_record() { Studentt={0,"",0,0,0,0}; printf("学号: ");/*交互输入*/ scanf("%d",&t.num); printf("姓名: "); scanf("%s",t.name); printf("语文: "); scanf("%lf",&t.chi); printf("数学: "); scanf("%lf",&t.math); printf("英语: "); scanf("%lf",&t.eng); returnt; } voidinput_record()/*输入若干条记录*/ { charchoice='y'; while(choice=='Y'||choice=='y')/*判断*/ { Stud[Student_Count]=input_a_record(); printf("还有更多的记录吗? (Y/N)"); Student_Count++; fflush(stdin);//清除输入缓冲区 choice=getchar(); } } voidcalc_total()//计算总分 { inti; for(i=0;i { Stud[i].total=Stud[i].chi+Stud[i].math+Stud[i].eng; } } voidmain()/*主函数*/ { intn=0; charchoice=''; while(choice! ='0') { display_menu(); fflush(stdin);//清空输入缓冲区 choice=getchar(); switch(choice) { case'1': //添加记录 input_record(); display_all_record(); break; case'2': //显示所有记录 calc_total(); display_all_record(); break; case'0': printf("感谢您使用本程序,再见! \n");/*结束程序*/ } } } 问题: (1)主函数中的循环在满足什么条件的情况下退出? (2)程序中,哪些地方执行了清除输入缓冲区? (3)如果需要实现程序中的其它功能,应该在什么位置补充内容? //给程序增加功能3(按学号排序并输出) voidsort_by_num()//按学号排序 { inti,j; Studentt; for(i=0;i for(j=0;j if(Stud[j].num>Stud[j+1].num) { t=Stud[j]; Stud[j]=Stud[j+1]; Stud[j+1]=t; } } //将函数定义添加到程序中适当的地方,并在主函数的switch语句中添加如下分支: case'3': //按学号排序 calc_total(); sort_by_num(); display_all_record(); break; 问题: (4)当执行功能3时,程序执行几个分支功能? //功能4(按学生总分从大到小排序) voidsort_by_total() { } //给程序添加功能5(删除指定学号的学生记录) intDelete_record_by_num(intnum)/*按姓名查找,删除一条记录*/ { inti,j; intfound=-1;//记录查找到的记录下标 for(i=0;i { if(Stud[i].num==num) { found=i; break; } } if(found! =-1) { for(j=found;j { Stud[j]=Stud[j+1]; } Student_Count--; return0; } return(-1); } voidDelete_a_record() { intnum; printf("请输入要删除的学生学号: ");/*交互式问寻*/ scanf("%d",&num); if(Delete_record_by_num(num)==0) printf("删除成功"); else printf("删除失败"); } 问题: (5)程序中利用两个函数的调用完成删除功能。 你认为这样分离为两个函数,是否便利? 如果只用一个函数能否完成相同的功能? //功能6(成绩查询),输入一个学生的姓名,输出姓名相匹配的学生记录 //先完成如下函数的定义,再调用相关函数实现上述功能 Student*query_a_record_by_name(char*name) { } //添加功能7(成绩统计) voidStatistic()/*输出统计信息*/ { inti; Studentmax={-1,"最高分",0,0,0,0},aver={-1,"平均分",0,0,0,0}; for(i=0;i { aver.chi+=Stud[i].chi; aver.math+=Stud[i].math; aver.eng+=Stud[i].eng; aver.total+=Stud[i].total; if(Stud[i].chi>max.chi)max.chi=Stud[i].chi; if(Stud[i].math>max.math)max.math=Stud[i].math; if(Stud[i].eng>max.eng)max.eng=Stud[i].eng; if(Stud[i].total>max.total)max.total=Stud[i].total; } aver.chi=aver.chi/Student_Count; aver.math=aver.math/Student_Count; aver.eng=aver.eng/Student_Count; aver.total=aver.total/Student_Count; display_header(); display_a_record(&max); display_a_record(&aver); } //完善功能7(“成绩统计”),增加计算并显示各科及格率和优秀率的功能。 //添加功能8(从文本文件中读取数据) voidread_textfile()/*从文件中读入数据*/ { inti=0; FILE*fp;/*定义文件指针*/ charfilename[50]; printf("请输入读取的文件名(缺省为students.txt): \n"); fflush(stdin); gets(filename); if(strcmp(filename,"")==0) { strcpy(filename,"students.txt"); } if((fp=fopen(filename,"r"))==NULL)/*打开文件*/ { return(-1); } fscanf(fp,"%d",&Student_Count);/*读入总记录量*/ for(i=0;i { fscanf(fp,"%d",&Stud[i].num); fscanf(fp,"%s",Stud[i].name); fscanf(fp,"%lf,%lf,%lf",&Stud[i].chi,&Stud[i].math,&Stud[i].eng); } fclose(fp);/*关闭文件*/ } //完成write_textfile函数的功能。 并完善程序的功能9(保存成绩到文本文件中)。 要求所生成的文件格式符合项目的要求,能够被功能8(“从文本文件中读取成绩”)重新正确读入。 (3)调试、运行程序. 六、考核形式 根据实验报告质量,给以综合评分。 七、实验报告要求 实验报告除必备的实验目的、实验要求等要素外,应包含以下内容: (1)说明程序测试的过程和结果; (2)说明程序的运行流程; (3)完善功能3~功能9的代码段内容; (4)写出5个问题的答案; (5)所有的思考题答案。 八、思考题 (1)怎样声明结构休类型? tyepdef有什么作用? (2)怎样定义、初始化结构体变量? 怎样输入、访问结构体成员? (3)怎样实现一个控制台菜单? (4)模块化程序设计的要点是什么? 函数间的数据传递有哪些方式? 它们之间有什么异同点? (5)如何实现文本文件的读写操作? (6)简述冒泡排序的思路; (7)如何实现学生记录的增、删、改、查操作? (8)该程序在哪些方面还可以进一步改进?
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C语言程序设计II 语言程序设计 II 综合性 实验 资料