《C语言程序设计II》综合性实验资料.docx

上传人:b****0 文档编号:9421475 上传时间:2023-05-19 格式:DOCX 页数:19 大小:153.33KB
下载 相关 举报
《C语言程序设计II》综合性实验资料.docx_第1页
第1页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第2页
第2页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第3页
第3页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第4页
第4页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第5页
第5页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第6页
第6页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第7页
第7页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第8页
第8页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第9页
第9页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第10页
第10页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第11页
第11页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第12页
第12页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第13页
第13页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第14页
第14页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第15页
第15页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第16页
第16页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第17页
第17页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第18页
第18页 / 共19页
《C语言程序设计II》综合性实验资料.docx_第19页
第19页 / 共19页
亲,该文档总共19页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

《C语言程序设计II》综合性实验资料.docx

《《C语言程序设计II》综合性实验资料.docx》由会员分享,可在线阅读,更多相关《《C语言程序设计II》综合性实验资料.docx(19页珍藏版)》请在冰点文库上搜索。

《C语言程序设计II》综合性实验资料.docx

《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)该程序在哪些方面还可以进一步改进?

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 高等教育 > 军事

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2