1、《C语言应用》实验报告 题 目 学生成绩管理系统(链表版) 目 录 第1章需求分析 3 第2章总体设计 3 2。1 系统的程序流程图 3 2.2系统的全局变量和常量 3 2。3系统的函数介绍 3 第3章详细设计 3 3.1 主函数设计 3 3。2 录入函数设计 4 3。3 排序函数设计 4 3。4 查找函数设计 4 3。5修改函数设计 4 3。6插入函数设计 4 3.7 删除函数设计 4 3。8 保存函数设计 4 3.9 显示函数设计 4 3.10 退出函数设计 4 第4章测试 5 总结5 参考文献 5 附录程序源代码 5 第1章 第1章需求分析
2、 (1)能完成学生成绩的插入、查询、修改、删除、输出等功能; (2)采用单链表存储结构实现; (3)所有数据以外部文件方式保存 第2章 第2章总体设计 2。1 系统的程序流程图 绘制一个系统的总体程序流程图,主要展示系统从开始以后,可以经过哪些流程,最后结束. 按姓名修改某位同学的成绩按姓名修改某位同学的成绩输出链表内容输出链表内容进入系统 浏览初始学生信息 按姓名修改某位同学的成绩 输入同学的相关信息 查找 按姓名删除某位同学的成绩 初始学生成绩排序 浏览所有同学的信息及排名 插入新的成绩 查看初始学生总分及平均分 保存最终结果到可浏览文件 退出系统 主
3、菜单 统计 学生信息录入 2。2系统的全局变量和常量 系统全局变量int n;char a; 头文件: #include "stdio。h" #include ”time.h” #include ”string。h” #include ”stdlib.h" #include ”conio。h” 2.3系统的函数介绍 把系统中的每个函数的原型列出来,解释一下函数的返回值及形式参数的含义;最后,再介绍一下每个函数的功能. void Create(int n)//创建链表 void List() //输出链表内容 void list() //输
4、出链表所有内容 void save() //文件保存 void save1() //文件保存 void read() //文件读取 void read1() //文件读取 void SAVE(){ //保存到可浏览文件 void SAVE1() //保存到可浏览文件 void sort_data_copy(Lstu *p,Lstu *s)//交换排序时的值 void sort()//对初始成绩进行排序 void sort1()//对
5、所有数据进行排序 void search_print(Lstu *p)//输出查找信息 void search_choose() //选择按分数段查找方式 void search() //查找 void modify_choose(Lstu *p,int n)//选择修改方式 void modify() //按姓名修改 void Insert()//按序号插入 void del() //按姓名删除 void statistics()
6、 //成绩统计 int menu() //菜单(主界面) 第3章 第3章详细设计 按函数,写出函数的原型声明,并画出每个函数的程序流程图。 3。1 主函数设计 函数 3。2 录入函数设计 添加的信息包括学号(不允许重复)、姓名(不允许重复)、语文成绩、数学成绩和英语成绩,如流程图所示: 开始插入数据 输入学生成绩信息 调用类成员函数采用单链表保存数据 结束 调用类成员函数保存数据到文件中 本程序采用的是尾插法,就是每次将新申请的结点插在终端结点的后面,其执行过程如图所示. 尾
7、插法建立单链表操作示意图 3。3 排序函数设计 可按照学号、语文成绩、数学成绩、英语成绩和平均分分别排序。如图所示: 结束 输入排序编号 判断 抱歉,没有此排序 输出学生的信息 排序开始 N Y 3。4 查找函数设计 按姓名、学号和分数段查找学生成绩的流程图分别如下图4。3所示。 结束 输入要查找姓名 判断 抱歉没有该学生 输出该学生的信息 按姓名 查找开始 N Y 图4。3按姓名查找学生成绩信息流程图 在单链表中,即使知道被访问结点的位置i,也不能像顺序表那样直接按序号访问,而只能从头指针出发,设置一个工作指针p,顺next域逐个结点往下
8、搜索。当p指向某个结点时判断是否为第i个结点,若是则查找成功;否则,将工作指针p后移,即将p指向原来所指结点的后继结点。直到p为NULL时查找失败。单链表查找过程如图4.4所示。 图4。4单链表查找过程的示意图 按学号查询学生成绩信息同按姓名查找学生成绩信息,此处不再详细列出. (3)学生成绩修改模块 3.5修改函数设计 首先要查找与要修改数据相匹配的信息,若没有则返回失败。否则把相应的信息输出,然后再重新输入新的数据并保存到单链表。 返回主菜单 开始修改操作 输入姓名 姓名一致 执行修改功能 N Y 3。6插入函数设计 首先要确定插入数据的位置,执行插入操作,
9、然后再输入数据并保存到单链表。 开始插入操作 选择要插入的位置 判断插入的位置 执行插入功能 N Y 返回主菜单 3。7 删除函数设计 当选择删除功能时,首先输入要删除的同学的姓名,然后输入要删除的同学的学号,如果该同学存在并且姓名与学号匹配的上,则进行删除操作,否则返回失败。其流程图如下: 开始删除操作 输入姓名 姓名姓名一致 执行删除功能 返回主菜单 N Y 删除操作定义为将单链表的第i个结点删去.因为在单链表中结点ai存储地址在其前驱结点ai-1的指针域,所以必须首先找到ai-1的存储地址p,然后令p的next域指向ai 的后继结点,即把结点ai
10、从链上摘下来,最后释放结点ai的存储空间,如图4.6所示。 在单链表中删除结点指针的变化情况 3.8 保存函数设计 输入学生信息应保存到学生基本信息文件中,修改后的信息将可保存到可浏览的文件,如图所示: 开始保存操作 输入保存到文件名 判断文件名的格式 执行删除功能 返回主菜单 N Y 3.9 显示函数设计 从单链表表头遍历整个单链表,将所有数据输出。其部分代码如下: void read(){ //文件读取 FILE *fp; Lstu *p,*p1; if((fp=fopen("初始值二进制.txt”,"rb"))==NULL) {
11、 printf(”Cannot open the file\n”); exit(0); }head=(Lstu*)malloc(sizeof(Lstu)); p1=head; while(!feof(fp)){ p=(Lstu *)malloc(sizeof(Lstu)); if(fread(p,sizeof(Lstu),1,fp)==1) { p1—〉next=p; p1=p1—〉next; } }head=head->next;fc
12、lose(fp); } 3.10 退出函数设计 第4章 第4章测试 主要进行功能性测试,即验证各个功能模块是否正确运行。 可以采用运行系统进行截图的方法来验证系统结果的正确性. 在完成了系统各方面的设计后,并不是可以运行就完成的,为了保证系统性能的稳定性跟安全性等,就要对系统做测试。 测试环境如下: l 硬件:P4C 2。4GHz,500GB硬盘,2内存; l 软件:Windows 7 Personal SP1,分辨率1366*768,Microsoft Visual C++ 6.0。 运行的主界面如图所示: ① 点击1输入学生相关信息,如图所示: ② 浏览初始学生信息
13、如图所示: ③ 查看初始学生总分及平均分,如图所示: ④ 查找,如图所示: 按姓名查找: ⑤ 初始学生成绩排序,如图所示: 按平均成绩进行排序: ⑥ 插入新成绩,如图所示: ⑦ 按姓名修改某位学生的成绩,如图所示: 选择修改数学成绩: ⑧ 按姓名删除某位学生的成绩,如图所示: ⑨ 浏览所有学生的信息及排名,如图所示: ⑩ 保存最终结果到可浏览的文件中,如图所示: ⑾统计,如图所示: 总结 写这次实验课的收获和感想。 参考文献 附录 程序源代码 //程序名称:xsglxt。CPP //程序功能:采用链表与文件实现一个简单的学生成绩管理系统。 #includ
14、e ”stdio。h" #include ”time。h” #include "string。h” #include ”stdlib。h" #include ”conio.h” #define NULL 0 typedef struct Lstu{ int cla,ID; long num; char name[20]; char sex[20]; float chinese,math,english; float sum,ave; Lstu *next; }Lstu; Lstu *head; void Create(i
15、nt n){ //创建链表 Lstu *p,*s; int i; for(i=0;i〈n;i++){ if(i==0){ p=(Lstu *)malloc(sizeof(Lstu)); printf(”请输入第%d个人的信息\n",i+1); printf(”请输入班级: ");scanf("%d",&p—〉cla); printf("请输入学号: ”);scanf("%ld”,&p-〉num); printf(”请输入姓名: ");scanf(”%s”,p—〉nam
16、e); printf(”请输入性别: ”);scanf(”%s",p—>sex); printf("请输入语文成绩: ”);scanf(”%f”,&p—>chinese); printf("请输入数学成绩: ”);scanf("%f”,&p—>math); printf(”请输入英语成绩: ”);scanf("%f”,&p—〉english); p—〉sum=p—>chinese+p—〉math+p-〉english; p—〉ave=p-〉sum/3; head=p; if(n==1){ p—〉next=NULL;}}
17、 else{ s=(Lstu *)malloc(sizeof(Lstu)); printf(”请输入第%d个人的信息\n”,i+1); printf("请输入班级: ”);scanf("%d",&s—〉cla); printf(”请输入学号: ");scanf(”%ld”,&s->num); printf(”请输入姓名: ");scanf(”%s”,s-〉name); printf(”请输入性别: ”);scanf("%s",s—>sex); printf("请输入语文成绩: ”);scanf(”
18、%f”,&s—〉chinese); printf(”请输入数学成绩: ");scanf("%f”,&s—〉math); printf(”请输入英语成绩: ");scanf(”%f”,&s—>english); s—>sum=s—〉chinese+s-〉math+s—〉english; s—>ave=s—>sum/3; p-〉next=s; p=s; s-〉next=NULL;} } } void List(){ //输出链表内容 Lstu *p; int i=0; p=head
19、 if(p==NULL){ printf("Sorry,It's a Empty List\n”);} else{ printf(”\n\n\t—---———-————-—————————————-——-——----—-————-————-———-—----—————————\n”); printf(”\t%-5s%—5s %—10s%-8s%—7s%-10s%—10s%—10s\n",”序号”,”班级”,”学号”,"姓名","性别","语文成绩",”数学成绩”,”英语成绩”); printf(”\t--——————-—-———-——-——-——————-
20、—--—————-—————————----————-——-—----———\n”); while (p){i++;p—〉ID=i; printf(”\t %—4d%-5d %-7d %—8s%—7s%-10.2f%-10.2f%—10。2f\n",p—>ID,p—〉cla,p->num,p-〉name,p—>sex,p—>chinese,p—>math,p—〉english); printf(”\t-———----———-—-———-——-—--————----————————---———-—-———--——--——-—————\n”); p=
21、p—〉next; } } } void list(){ //输出链表所有内容 Lstu *p; int i=0; p=head; if(p==NULL){ printf("Sorry,It’s a Empty List\n”);} else{ printf("\n ———-——-—--—-———--———--—-——————---—-—-———-———-————---—-—————-——————--———-—-—--—-—-—\n”); printf(” %—5s%-5s %—7s
22、 %—8s%—7s%-10s%—10s%—10s%—8s%—8s\n","序号”,”班级","学号”,”姓名",”性别",”语文成绩”,”数学成绩", "英语成绩”,”总分",”平均分"); printf(” ---——————-—-——-—-———-—-—-—————----——————-—---——-—-—-———--—————-—-———-----————-————\n"); while (p){i++;p—〉ID=i; printf(" %-4d%—6d%-12d%—8s%—7s%—10.2f%—10。2f%—10.2f%-8。2f%—8。2f\n"
23、p-〉ID,p->cla,p—〉num,p—〉name,p—>sex, p-〉chinese,p-〉math,p—〉english,p->sum,p—〉ave); printf(” ———————-——----—————-——-—-—-———--——--———------———————-—————-—-—-—-————————-————————\n”); p=p—〉next; } } } void save(){ //文件保存 FILE *fp; Lstu *p; p=head; if
24、fp=fopen(”初始值二进制.txt”,"wb"))==NULL) { printf("Cannot open the file "); exit(0); } while(p){ fwrite(p,sizeof(Lstu),1,fp); p=p—>next;} fclose(fp); } void save1(){ //文件保存 FILE *fp; Lstu *p; p=head; if((fp=fopen("初始值二进制备用。txt”,”wb”))==NULL) { p
25、rintf("Cannot open the file ”); exit(0); } while(p){ fwrite(p,sizeof(Lstu),1,fp); p=p-〉next;} fclose(fp); } void read(){ //文件读取 FILE *fp; Lstu *p,*p1; if((fp=fopen("初始值二进制。txt”,”rb”))==NULL) { printf(”Cannot open the file\n”); exit(0); }head=(Lstu*
26、malloc(sizeof(Lstu)); p1=head; while(!feof(fp)){ p=(Lstu *)malloc(sizeof(Lstu)); if(fread(p,sizeof(Lstu),1,fp)==1) { p1—〉next=p; p1=p1—〉next; } }head=head—〉next;fclose(fp); } void read1(){ //文件读取 FILE *fp; Lstu *p,*p1; if((fp
27、fopen(”初始值二进制备用。txt”,”rb”))==NULL) { printf(”Cannot open the file\n"); exit(0); }head=(Lstu*)malloc(sizeof(Lstu)); p1=head; while(!feof(fp)){ p=(Lstu *)malloc(sizeof(Lstu)); if(fread(p,sizeof(Lstu),1,fp)==1) { p1—〉next=p; p1=p1
28、—〉next; } }head=head—〉next;fclose(fp); } void SAVE(){ //保存到可浏览文件 FILE *fp; Lstu *p;int i=0; p=head; if((fp=fopen(”初始值可浏览文件。txt”,”w+"))==NULL) { printf(”Cannot open the file ”); exit(0); } fprintf(fp,"\n\n\t——--—-———-----—-——-——-———-—--————
29、—----—-—--——-———-----——--———--—-—\n"); fprintf(fp,”\t%-5s%—5s %-10s%—8s%-7s%—10s%—10s%-10s\n”,"序号","班级”,”学号”,”姓名”,"性别",”语文成绩”,"数学成绩",”英语成绩"); fprintf(fp,"\t—-—————-—-——--—---—-—————-————--—--——-—-—————---———————-——-—————-—\n\n"); while(p){ i++;p->ID=i; fprintf(fp,”\t %-4d%-5d %—7d
30、 %-8s%—7s%—10.2f%-10。2f%-10.2f\n",p—〉ID,p—〉cla,p-〉num,p—>name, p—〉sex,p-〉chinese,p—〉math,p-〉english); fprintf(fp,"\t——---——--—-——-—-——-———-—-—-----————-——--———-——--—--—-———---—-——-——\n”); p=p—〉next; } fclose(fp); } void SAVE1(){ //保存到可浏览文件 FILE *fp;char filen
31、ame[20]; Lstu *p;int i=0; p=head; printf("请输入保存到可浏览文件的文件名: "); scanf(”%s”,filename); if((fp=fopen(filename,"w+"))==NULL) { printf(”Cannot open the file ”); exit(0); } fprintf(fp,”\n —-———--—-—----——--—---————-—-—————-—————————-——————-—---——---——-—-————-----—--
32、—---\n”); fprintf(fp,” %—5s%-5s %-7s %—8s%—7s%-10s%—10s%-10s%—8s%-8s\n",”序号","班级”,"学号”,”姓名","性别”,”语文成绩”,”数学成绩", ”英语成绩","总分","平均分”); fprintf(fp,” ——--——-—-—--——-————-——-——-—-—--—-——-——--————-——--——--———————————---————-—-—-———-—-\n”); while(p){ i++;p—>ID=i; fprintf(fp,” %—
33、4d%—5d %—7d %—8s%-7s%-10。2f%-10.2f%—10.2f%—8.2f%—8。2f\n",p—〉ID,p-〉cla,p-〉num,p—>name,p—〉sex, p—〉chinese,p-〉math,p—>english,p-〉sum,p-〉ave); fprintf(fp,”-—-——--—--—--—-————-————————--—-————--———--——--—-———--——-—--——--———-————-——----\n"); p=p—〉next; } fclose(fp); } void
34、sort_data_copy(Lstu *p,Lstu *s){ //交换排序时的值 int cla1; cla1=p—>cla;p—〉cla=s->cla;s—〉cla=cla1; long num1; num1=p—〉num;p-〉num=s—>num;s-〉num=num1; char name1[20]; strcpy(name1,p->name);strcpy(p—〉name,s—〉name);strcpy(s—〉name,name1); char sex1[20]; strcpy(sex1,p—〉sex);strcpy(p-〉sex,s—
35、>sex);strcpy(s->sex,sex1); float chinese1; chinese1=p->chinese;p->chinese=s->chinese;s-〉chinese=chinese1; float math1; math1=p—〉math;p-〉math=s->math;s-〉math=math1; float english1; english1=p—>english;p—>english=s-〉english;s->english=english1; float sum1; sum1=p—〉sum;p—〉sum=s—〉sum;s—〉
36、sum=sum1; float ave1; ave1=p-〉ave;p-〉ave=s—〉ave;s-〉ave=ave1; } void sort(){ //对初始成绩进行排序 Lstu *p,*s; int n;char a; read();p=head; if(p==NULL){ printf(”Sorry,It's a Empty List\n”); printf("\n按Enter键继续\n”);a=getch();} else{while(1){system(”cls”);printf("\n排序前结果为:\n");read()
37、list(); printf(”\t *=*=*=*=*=*=*=*=*=*=*=按学号排序(1)\n"); printf(”\t *=*=*=*=*=*=*=*=*=*=*=按语文成绩排序(2)\n”); printf(”\t *=*=*=*=*=*=*=*=*=*=*=按数学成绩排序(3)\n"); printf(”\t *=*=*=*=*=*=*=*=*=*=*=按英语成绩排序(4)\n”); printf("\t *=*=*=*=*=*=*=*=*=*=*=按平均分排序(5)\n”); printf(”\t *=*=*
38、*=*=*=*=*=*=*=回主菜单(0)\n\n”);
printf(”\t请输入选择: ”);
scanf("%d”,&n);
for(p=head;p-〉next!=NULL;p=p-〉next)
for(s=p-〉next;s!=NULL;s=s—>next)
switch(n){
case 1: if(p-〉num>s-〉num){sort_data_copy(p,s);}break;
case 2: if(p—>chinese 39、case 3: if(p—〉math 40、else{printf("排序后结果为:\n”);
list();SAVE1();printf("\n按Enter键继续\n”);a=getch();}}}
}
void sort1(){ //对所有数据进行排序
Lstu *p,*s;
int n;char a;
read1();p=head;
if(p==NULL){
printf(”Sorry,It’s a Empty List\n”);
printf(”\n按Enter键继续\n”);a=getch();}
else{while(1){system(”cls”);printf("\ 41、n排序前结果为:\n");read1();list();
printf(”\t *=*=*=*=*=*=*=*=*=*=*=按学号排序(1)\n”);
printf("\t *=*=*=*=*=*=*=*=*=*=*=按语文成绩排序(2)\n”);
printf(”\t *=*=*=*=*=*=*=*=*=*=*=按数学成绩排序(3)\n”);
printf("\t *=*=*=*=*=*=*=*=*=*=*=按英语成绩排序(4)\n”);
printf("\t *=*=*=*=*=*=*=*=*=*=*=按平均分排序(5)\n”);
42、
printf(”\t *=*=*=*=*=*=*=*=*=*=*=回主菜单(0)\n\n");
printf("\t请输入选择: ”);
scanf(”%d",&n);
for(p=head;p->next!=NULL;p=p—〉next)
for(s=p—>next;s!=NULL;s=s-〉next)
switch(n){
case 1: if(p—〉num>s-〉num){sort_data_copy(p,s);}break;
case 2: if(p—〉chinese 43、opy(p,s);}break;
case 3: if(p—>math〈s-〉math){sort_data_copy(p,s);}break;
case 4: if(p—〉english〈s—〉english){sort_data_copy(p,s);}break;
case 5: if(p—>ave〉s-〉ave){sort_data_copy(p,s);}break;
case 0: break;
default : printf(”chooe error!”);break;}
if(n==0){printf("\n按Enter键回主菜单\n");a 44、getch();break;}
else{printf(”排序后结果为:\n");
list();SAVE1();printf(”\n按Enter键继续\n”);a=getch();}}}
}
void search_print(Lstu *p){ //输出查找信息
printf(”\t————----—-—-—-—-—-———-----———-——-———-———-——————-——-—-—--——--—\n");
printf(”\t%-5s %—7s %—8s%—7s%—10s%—10s%-10s\n”,"班级","学号” 45、姓名”,"性别”,”语文成绩”,”数学成绩",”英语成绩");
printf(”\t——---—-———-——-—-—--——-————-———-———-——-—-——---—---———--——-—-——\n");
printf(”\t%—5d %—7d %-8s%—7s%—10。2f%—10.2f%—10.2f\n”,p—〉cla,p->num,p—〉name,p—〉sex,p-〉chinese,p—〉math,p—>english);
printf(”\t———-——-—---———-———-——---—-—-—-—-——--—————--————-—————-———— 46、——\n”);
}
void search_choose(){ //选择按分数段查找方式
Lstu *p;
int n,i=1,flag=0;
float a,b;
p=head;
printf(”\t*=*=*=*=*=*=*=*=*=*=*=按语文分数段查找(1)\n");
printf(”\t*=*=*=*=*=*=*=*=*=*=*=按数学分数段查找(2)\n”);
printf(”\t*=*=*=*=*=*=*=*=*=*=*=按英语分数段查找(3)\n\n”);
printf(”\t请输入选择: ”) 47、
scanf("%d”,&n);
printf(”请输入分数下限(包括输入的分数): ”);
scanf(”%f”,&a);
printf("请输入分数上限(包括输入的分数): ");
scanf(”%f",&b);
switch(n){
case 1: while(p){
if((p—〉chinese)〉=a&&(p—>chinese)〈=b){
flag=1;} p=p—〉next;
}
if(flag==0){
printf(”没有此分数段的同学!\n");}
48、 else{printf(”您所查找的同学信息如下:\n");
printf("\t-———-——-———-——--———---—————--————-—--—-————-—--—-—--————-———-\n");
printf(”\t%-5s %—7s %-8s%—7s%—10s%-10s%—10s\n”,”班级”,”学号”,"姓名",”性别”,”语文成绩”,”数学成绩","英语成绩”);
p=head;
printf(”\t————-—-——-—--—-—-—-—————————-—————-——- 49、—-————-—--————-—————---\n”);
while(p){
if((p-〉chinese)〉=a&&(p—〉chinese)〈=b){
printf(”\t%—5d %—7d %-8s%-7s%-10。2f%-10。2f%—10.2f\n”,p—〉cla,p—〉num,p—〉name,p-〉sex,p—〉chinese,p—〉math,p—>english);
printf("\t----—————-———————-—--————-—————————--——--——-—-——-——---——— 50、———-\n”);}
p=p—>next;
}}break;
case 2: while(p){
if((p—〉chinese)>=a&&(p—〉math)〈=b){
flag=1;} p=p-〉next;
}
if(flag==0){
printf(”没有此分数段的同学!\n”);}
else{printf(”您所查找的同学信息如下:\n");
printf("\t-—--—————-—————---—-—-——-————-—--—chinese){sort_data_c






