当前位置: 首页 > >

武汉科技大学C语言课程设计实验报告

发布时间:

二○一二 ~二○一三 学年第 一 学期

电子技术学院

课程设计报告书
课程名称: 班 学 姓 级: 号: 名: C 程序课程设计 电信 DB2011 级 1102 班 XXXXXXXXX XXXX 陈彬

指导教师:

二○一二年 九 月

一、需求分析
1、题目二 学生成绩管理程序 任务:自学 C 语言中相关知识,设计出学生成绩管理程序。要求如下所述: ? 录入学生信息,每位学生录入的信息有:姓名、学号、性别、班级、和三门 功课(数学,英语,计算机)的成绩。以文件(myfile.txt)的形式保存每个 学生的所有信息。 (实验中:假设 3 个班,每个班学生人数不得少于 5 人) 学号 1101 1102 1103 姓名 王鹏 李燕 赵亚芳 性别 男 女 女 班级 1班 2班 3班 数学 70 68 58 英语 计算机 58 88 48 98 95 96

? 增加学生记录,并将增加的信息以文件的(myfile.txt)的形式保存。 ? 删除学生记录,以“学号”“姓名”为关键字删除记录,若要删除的记录不 、 存在,给出必要的提示信息; ? 统计各班级学生每门课程的班级*均分,并由高到低排序。 ? 按学号或者姓名查询记录并显示其三门功课成绩; ? 能浏览显示全部学生成绩,若无记录可以显示,给出必要的提示信息; 2、系统功能需求分析 该程序中需要有存储、读取外部文件的命令实现将信息储存于指定文件中。 程序中需要有建立、 修改链表的命令实现数据的动态链表存储方式。程序还需要 一系列的提示命令使程序的易用性提高。因为需要对数据进行统计或查询显示, 所以需要有对链表数据统计和对链表指定数据进行查找的功能。

二、概要设计
学生成绩管理程序

成绩 单建 立模 块

数据 增加 模块

数据 删除 模块

数据 查找 模块

数据 显示 模块

成绩 对比 模块

数据 保存 模块

文件 读取 模块

三、详细设计
1、建立结构体 struct student { int num; char name[10],sex[10]; int Class,math,english,computer; struct student * next; }; int n; 2、成绩单建立模块
开始

struct student *head,*p1,*p2; n=0; p1=p2=(struct student *)malloc(LEN);

输入第一个学生的数据

head=NULL;

p1->num!=0

Y N
链表指针向后移动

输入一个学生的数据

输入学号为“0”

Y

N

p2->next=NULL; return(head);

结束

struct student *creat(void) { struct student *head,*p1,*p2; n=0; p1=p2=(struct student *)malloc(LEN); printf("请输入学生信息(按学号顺序输入)\n"); printf("学号:"); scanf("%d",&p1->num); printf("姓名:"); scanf("%s",p1->name); printf("性别:"); scanf("%s",p1->sex); printf("班级:"); scanf("%d",&p1->Class); printf("数学:"); scanf("%d",&p1->math); printf("英语:"); scanf("%d",&p1->english); printf("计算机:"); scanf("%d",&p1->computer); head=NULL; while(1) { n=n+1; if(n==1) head=p1; else p2->next=p1; p2=p1; p1=(struct student *)malloc(LEN); printf("\n 请输入学生信息(按学号顺序输入)[当不再输入时在学号处 输入\"0\"结束]\n"); printf("学号:");scanf("%d",&p1->num); if(p1->num==0)break; else printf("姓名:"); scanf("%s",p1->name); printf("性别:"); scanf("%s",p1->sex); printf("班级:"); scanf("%d",&p1->Class); printf("数学:"); scanf("%d",&p1->math); printf("英语:"); scanf("%d",&p1->english); printf("计算机:"); scanf("%d",&p1->computer); } p2->next=NULL; return(head); } 3、数据增加模块

开始

struct student *p0,*p1,*p2; p1=head; p0=stud; phead; p0=stud; 输入一个学生的数据

根据学号顺序找到数据应该插入的位置 phead; p0=stud; 插入数据 返回头指针 phead; p0=stud; 结束

struct student *insert(struct student *head,struct student *stud) { struct student *p0,*p1,*p2; p1=head; p0=stud; if(head==NULL) {head=p0; p0->next=NULL;} else { while((p0->num>p1->num)&&(p1->next!=NULL)) {p2=p1; p1=p1->next;} if(p0->num<=p1->num) { if(head==p1) head=p0; else p2->next=p0; p0->next=p1; } else {p1->next=p0; p0->next=NULL;} } n++; printf("\n 增加成功!\n"); return(head); }

4、数据删除模块

开始

struct student *p1,*p2;

输入删除的学号(姓名)

链表中有该数据

Y
p1==head

Y N
head=p1->next

p2->next=p1->next;

printf(“不到该数据!\n");

结束

struct student *del1(struct student *head,int num) { struct student *p1,*p2; if(head==NULL) {printf("\n 表格不存在!\n"); return(head);} p1=head; while((num!=p1->num)&&(p1->next!=NULL)) {p2=p1; p1=p1->next;} if(num==p1->num) { if(p1==head) head=p1->next;

else p2->next=p1->next; printf("\n 删除成功!\n"); n--; } else printf("\n 找不到该数据!\n"); return(head); } struct student *del2(struct student *head,char *name) { struct student *p1,*p2; if(head==NULL) {printf("\n 表格不存在!\n"); return(head);} p1=head; while((strcmp(name,p1->name)!=0)&&(p1->next!=NULL)) {p2=p1; p1=p1->next;} if(strcmp(name,p1->name)==0) { if(p1==head) head=p1->next; else p2->next=p1->next; printf("\n 删除成功!\n"); n--; } else printf("\n 找不到该数据!\n"); return(head); } 5、数据查找模块

开始 struct student *p=head;

输入查找的学号(姓名)

num==p->num 或 strcmp(name,p->name)==0

N

Y
输出数据 Y

p=p->next

N

p!=NULL

Y
结束

void find1(struct student *head,int num) { struct student *p=head; if(head!=NULL) { do { if(num==p->num) { printf("\n 学号 姓名 性别 \n");

班级

数学

英语

计算机

printf("--------------------------------------------\n"); printf("%d %-6s %s %d %-3d %-3d %-3d\n",p->num,p->name ,p->sex,p->Class,p->math,p->english,p->computer); break;

} else p=p->next; }while(p!=NULL); if(p==NULL) printf("\n 未找到相应信息!\n"); } else printf("\n 成绩单为空!\n"); } void find2(struct student *head,char *name) { struct student *p=head; if(head!=NULL) { do { if(strcmp(name,p->name)==0) { printf("\n 学号 姓名 性别 \n");

班级

数学

英语

计算机

printf("--------------------------------------------\n"); printf("%d %-6s %s %d %-3d %-3d %-3d\n",p->num,p->name ,p->sex,p->Class,p->math,p->english,p->computer); break; } else p=p->next; }while(p!=NULL); if(p==NULL) printf("\n 未找到相应信息!\n"); } else printf("\n 成绩单为空!\n"); } void print(struct student *head) { struct student *p; p=head; if(head!=NULL) { printf("学号 姓名 性别 班级 数学 英语 计算机\n"); printf("--------------------------------------------\n"); do {

printf("%d %-6s %s %d %-3d %-3d %-3d\n",p->num,p-> name,p->sex,p->Class,p->math,p->english,p->computer); p=p->next; }while(p!=NULL); } else printf("无信息!\n"); } 6、数据显示模块

开始 struct student *p; p=head;

head!=NULL

Y
输出一个学生的数据

N

p=p->next;

Y
p!=NULL

N
结束

void print(struct student *head) { struct student *p; p=head; if(head!=NULL) { printf("学号 姓名 性别 班级 数学 英语 计算机\n"); printf("--------------------------------------------\n"); do { printf("%d %-6s %s %d %-3d %-3d %-3d\n",p->num,p-> name,p->sex,p->Class,p->math,p->english,p->computer);

p=p->next; }while(p!=NULL); } else } printf("无信息!\n");

7、成绩对比模块
开始 struct student *p; p=head; float sum1=0,sum2=0,sum3=0,average1,average2,average3,n1=0,n2=0,n3=0;

N

p!=NULL

Y Y
p->Class==1

N
p->Class==2

sum1=sum1+p->math(englishi/computer); n1++;

Y N
sum1=sum1+p->math(englishi/computer); n1++;

p->Class==3

Y
sum1=sum1+p->math(englishi/computer); n1++;

p=p->next; 算出各班*均分并比较

输出成绩对比结果

结束

void compare(struct student *head) { struct student *p; p=head;

float sum1=0,sum2=0,sum3=0,average1,average2,average3,n1=0,n2=0,n3=0; printf(" ◎ 数学班级*均分 ◎ \n"); printf("--------------------------------------\n"); while(p!=NULL) { if(p->Class==1) {sum1=sum1+p->math; n1++;} if(p->Class==2) {sum2=sum2+p->math; n2++;} if(p->Class==3) {sum3=sum3+p->math; n3++;} p=p->next; } average1=sum1/n1; average2=sum2/n2; average3=sum3/n3; if((average1>=average2)&&(average1>=average3)) { if(average2>=average3) printf("1 班 : %.2f 2 班 : %.2f 班:%.2f\n",average1,average2,average3); else printf("1 班 : %.2f 3 班 : %.2f 班:%.2f\n",average1,average3,average2); } else { if((average2>=average1)&&(average2>=average3)) { if(average1>=average3) printf("2 班 : %.2f 1 班 : %.2f 班:%.2f\n",average2,average1,average3); else printf("2 班 : %.2f 3 班 : %.2f 班:%.2f\n",average2,average3,average1); } else { if(average1>=average2) printf("3 班 : %.2f 1 班 : %.2f 班:%.2f\n",average3,average1,average2); else printf("3 班 : %.2f 2 班 : %.2f 班:%.2f\n",average3,average2,average1); } } p=head;sum1=0;sum2=0;sum3=0;n1=0;n2=0;n3=0; printf("\n ◎ 英语班级*均分 ◎ \n");

3

2

3

1

2

1

printf("--------------------------------------\n"); while(p!=NULL) { if(p->Class==1) {sum1=sum1+p->english; n1++;} if(p->Class==2) {sum2=sum2+p->english; n2++;} if(p->Class==3) {sum3=sum3+p->english; n3++;} p=p->next; } average1=sum1/n1; average2=sum2/n2; average3=sum3/n3; if((average1>=average2)&&(average1>=average3)) { if(average2>=average3) printf("1 班 : %.2f 2 班 : %.2f 班:%.2f\n",average1,average2,average3); else printf("1 班 : %.2f 3 班 : %.2f 班:%.2f\n",average1,average3,average2); } else { if((average2>=average1)&&(average2>=average3)) { if(average1>=average3) printf("2 班 : %.2f 1 班 : %.2f 班:%.2f\n",average2,average1,average3); else printf("2 班 : %.2f 3 班 : %.2f 班:%.2f\n",average2,average3,average1); } else { if(average1>=average2) printf("3 班 : %.2f 1 班 : %.2f 班:%.2f\n",average3,average1,average2); else printf("3 班 : %.2f 2 班 : %.2f 班:%.2f\n",average3,average2,average1); } } p=head;sum1=0;sum2=0;sum3=0;n1=0;n2=0;n3=0; printf("\n ◎ 计算机班级*均分 ◎ \n"); printf("--------------------------------------\n"); while(p!=NULL) {

3

2

3

1

2

1

if(p->Class==1) {sum1=sum1+p->computer; n1++;} if(p->Class==2) {sum2=sum2+p->computer; n2++;} if(p->Class==3) {sum3=sum3+p->computer; n3++;} p=p->next; } average1=sum1/n1; average2=sum2/n2; average3=sum3/n3; if((average1>=average2)&&(average1>=average3)) { if(average2>=average3) printf("1 班 : %.2f 2 班 : %.2f 班:%.2f\n",average1,average2,average3); else printf("1 班 : %.2f 3 班 : %.2f 班:%.2f\n",average1,average3,average2); } else { if((average2>=average1)&&(average2>=average3)) { if(average1>=average3) printf("2 班 : %.2f 1 班 : %.2f 班:%.2f\n",average2,average1,average3); else printf("2 班 : %.2f 3 班 : %.2f 班:%.2f\n",average2,average3,average1); } else { if(average1>=average2) printf("3 班 : %.2f 1 班 : %.2f 班:%.2f\n",average3,average1,average2); else printf("3 班 : %.2f 2 班 : %.2f 班:%.2f\n",average3,average2,average1); } } } 8、数据保存模块 void save(struct student *head) { struct student *p; FILE *fp; fp=fopen("myfile.txt","wb");

3

2

3

1

2

1

p=head; while(p!=NULL) {fwrite(p,LEN,1,fp); p=p->next;} fclose(fp); printf("保存成功!\n"); } 9、数据读取模块 struct student *load() { struct student *head,*p1,*p2; FILE *fp; n=0; head=NULL; fp=fopen("myfile.txt","rb"); head=p2=p1=(struct student *)malloc(LEN); while(fread(p1,LEN,1,fp)==1) { p2=p1; p1=(struct student *)malloc(LEN); p2->next=p1; n++; } p2->next=NULL; fclose(fp); printf("读取成功!\n"); return(head); } 10、主函数 void main() { system("color 0B"); struct student *head=NULL,*stu; int num,choice; char name[10]; while(1) { system("pause"); system("cls"); printf("# # # # # # # # # # # # # # # # # # # # # # # #\n"); printf("# #\n"); printf("# ☆★☆ 学生成绩管理系统菜单 ☆★☆ #\n"); printf("#---------------------------------------------#\n"); printf("# 1.创建学生成绩单 #\n"); printf("#---------------------------------------------#\n");

printf("# 2.增加学生信息 #\n"); printf("#---------------------------------------------#\n"); printf("# 3.删除学生信息 #\n"); printf("#---------------------------------------------#\n"); printf("# 4.查看学生信息 #\n"); printf("#---------------------------------------------#\n"); printf("# 5.显示所有学生信息 #\n"); printf("#---------------------------------------------#\n"); printf("# 6.班级成绩对比 #\n"); printf("#---------------------------------------------#\n"); printf("# 7.保存至文件 #\n"); printf("#---------------------------------------------#\n"); printf("# 8.从文件中读取信息 #\n"); printf("#---------------------------------------------#\n"); printf("# 9.退出系统 #\n"); printf("# #\n"); printf("# # # # # # # # # # # # # # # # # # # # # # # #\n"); printf("\n 请选择所需功能:"); scanf("%d",&choice); printf("\n"); switch(choice) { case 1: head=creat(); break; case 2: stu=(struct student *)malloc(LEN); printf("请输入学生信息\n"); printf("学号:"); scanf("%d",&stu->num); printf("姓名:"); scanf("%s",stu->name); printf("性别:"); scanf("%s",stu->sex); printf("班级:"); scanf("%d",&stu->Class); printf("数学:"); scanf("%d",&stu->math); printf("英语:"); scanf("%d",&stu->english); printf("计算机:"); scanf("%d",&stu->computer); while(1) { head=insert(head,stu); printf("请继续输入学生信息(按\"0\"退出)\n"); stu=(struct student *)malloc(LEN); printf("学号:"); scanf("%d",&stu->num); if(stu->num==0) break; printf("姓名:"); scanf("%s",stu->name); printf("性别:"); scanf("%s",stu->sex); printf("班级:"); scanf("%d",&stu->Class); printf("数学:"); scanf("%d",&stu->math); printf("英语:"); scanf("%d",&stu->english);

printf(" 计 算 机 : "); scanf("%d",&stu->computer); } break; case 3: printf("1.按学号删除 2.按姓名删除\n 请选择:"); scanf("%d",&choice); switch(choice) { case 1: printf("输入要删除的学生学号(按\"0\"退 出):"); scanf("%d",&num); while(num!=0) { head=del1(head,num); printf("输入要删除的学生学号(按 \"0\"退出):"); scanf("%d",&num); } break; case 2: printf("输入要删除的学生姓名(按\"0\"退 出):"); scanf("%s",name); while(strcmp(name,"0")!=0) { head=del2(head,name); printf("输入要删除的学生姓名(按 \"0\"退出):"); scanf("%s",name); } break; default: break; } break; case 4: printf("1.按学号查找 2.按姓名查找\n 请选择:"); scanf("%d",&choice); switch(choice) { case 1: printf("输入要查找的学生学号:"); scanf("%d",&num); find1(head,num); break; case 2: printf("输入要查找的学生姓名:"); scanf("%s",name); find2(head,name);

break; default: break; } break; case 5: print(head); break; case 6: compare(head); break; case 7: save(head); break; case 8: head=load(); break; default: break; } if(choice==9) {printf("谢谢使用!\n"); break;} } }

四、调试分析过程描述
1、主菜单

2、创建成绩单

3、增加学生记录

4、删除学生记录

5、显示所有学生记录

6、班级成绩对比

7、查找学生记录

8、保存学生记录

9、读取文件信息

调试过程中的问题与反思: 此次编写的程序盖内容量很大, 在编写过程中采用的是写好一个模块测试一 个模块的方法, 但是将各个模块组合到一起后仍旧出现了许多小问题,经过多次 调试才达到各个模块协调工作。 最初程序编写的时候并没有太过提示性输出语句, 虽然程序运行不会受到影 响, 但是非编写人员就难以使用,在调试中明显感受到有些地方如果不加提示使 用者将很难操作。 最后对一些需要提示的地方慢慢修改,加入一系列提示以后才 使程序比较人性化。对于界面的设计,最初虽然有一个雏形,但是在实际调试过 程中暴露出不少错位等显示效果不佳的状况。 针对此类问题, 必须多次全面调试, 才能将程序界面编写得最美观。

经过整个调试之后, 深深感受到程序调试有相当的必要性,很多问题不经过 反复调试是难以暴露的。如界面设计、菜单人性化等需要直观感受的东西,也只 有通过程序调试才能将它们尽可能完善。

五、课程设计小结
通过本次课程设计,我熟悉了对链表的创建、增加、删除等一些操作,先前 只在课堂上听老师讲述, 自己对开辟内存空间、结构体指针等与链表相关的操作 并不熟悉,在制作了这个程序之后,我对链表的相关操作已经比较熟练了。 本次课程设计需要用到一系列外部文件命令, 通过自学外部命令和课程设计 的演练,我已经能够掌握外部文件的相关命令。值得一提的是,课程设计要求链 表命令与外部文件命令相结合,通过此次程序编写,这两部分知识结合使用,将 我所学的只是串联起来。 课程设计所要求的程序, 是我从学* C 语言以来编写得最长的程序,以往老 师在可能上常说命令要精简我总是不以为然,经过本次编写,我体会到了精简命 令的重要性。对于一个小程序,可能长点短点无所谓,出了问题很容易检查,而 对于这种需要编写四五百行的大程序,如果不注意使用命令的简单明了,可能导 致程序编写量大很多,冗长的程序代码也会给程序出错时的检查带来极大的麻 烦。 过去编写程序,都是书上的题目,完成题目就算目标达成。而此次程序设计 我需要完成的是一个完完整整有很强使用行的程序。 因而首次让我注意到界面的 问题,不仅仅需要编写出能够正常运行的程序,还需要给使用者一个清爽的、易 操作的界面。为了达到清爽的界面,得不断观察程序运行界面,不断调试,达到 最佳显示效果; 为了达到一操作性,必需添加一系列判断语句同时伴随相应的输 出语句给使用者提示。这些,都是过去 C 语言练*中涉及不多的。 这次设计的程序包含了大量的独立模块, 在编写过程中运用了逐个模块单独 编写,单独测试,最终聚合到一起调试的思路。这种思路以前大学计算机基础课 和 C 语言课都讲到过,但由于所编写的程序往往比较简单,过去并未应用。而此 次课程设计运用到了这种思想, 我也感受到了这种思想的先进性,大大提高了工 作效率。

总之,在这次课程设计中我受益匪浅,我不仅掌握了过去并未掌握的知识, 同时将很多以前随听说却不曾使用过的思想付诸实践。 也体会到调试程序的重要 性,从调试中我们可以发现很多很多编写时所未曾注意的问题。C 语言这门课, 是教我们如何编写程序,绝非仅仅会解答 C 语言题目,从编写程序过程中,我感 受到还要注重程序界面的外观与可操作性。




友情链接: