铜陵学院 班级成绩管理系统的设计与实现
发布时间:2024-11-28
发布时间:2024-11-28
铜陵学院 班级成绩管理系统的设计与实现 只需添加名字 学号
综合性实验报告
课程名称:
《C语言程序设计》
实验题目: 班级成绩管理系统的设计与实现
姓名学号:
系 别:
电气工程系
专业班级:
指导教师:
实验日期: 2012年06月01日—06月20日
一、实验目的和要求
实验目的
1、利用所学的三种程序基本结构以及数组、用户自定义函数进行一个小型程序的设计,进一步理解和掌握C语言的语法以及三种基本程序结构的综合应用。
铜陵学院 班级成绩管理系统的设计与实现 只需添加名字 学号
2、通过程序中涉及到的排序、查找、求和等操作加深对算法、程序设计思路、常用程序设计技巧的理解与掌握,逐步培养学生的程序开发能力。
实验要求
1、根据实验内容,认真编写源程序代码、上机调试程序,书写实验报告。 2、分小组协作实验时,要写明每一位学生负责的实验内容。 二、设计要求
(一)学生信息和程序功能
给定的原始数据和程序应实现的功能是该C程序开发的依据,此实验只处理一个班级学生信息,最多学生数为120人。
1、学生信息和数据类型
最多学生人数和最多课程数定义为全局符号常量:
#define Mmax 120 #define Nmax 3
(1)学生信息
学生信息包含:学号,姓名,三门课(语文,数学,英语)成绩和总分。 (2)数据类型
学号、姓名、课程三个信息为char型,课程分数和总分为float型,其余为int型。其中,假设学号有10位数字字符(注意此时要求存储空间要11个字节),例如2011023102表示入学年份为2011年,023是专业编码,102是学生在班级中的排号。
2、测试数据
测试数据在定义数组时以初值形式提供,其中学生总成绩通过程序计算。
学号 2011023001 2011023002 2011023003 2011023004 3、程序功能
(1)学生信息(学号、姓名、成绩等)的显示(数据结构要求用数组); (2)按姓名查找学生(数据结构要求用数组); (3)计算各门课程的平均分(数据结构要求用数组);
姓名 Zhang Li Cheng Wang
语文 73.5 83 65 71
数学 85 91.5 82 83
英语 67 87 78 80.5
但是,在用单链表处理学生信息时,要求直接从键盘上接收数据。
铜陵学院 班级成绩管理系统的设计与实现 只需添加名字 学号
(4)计算学生总成绩,并按总成绩进行排序(数据结构要求用数组); (5)按总成绩降序显示学生信息; (6)学生记录的插入;
(7)用单链表(结构体)处理班级学生信息(学号、姓名、成绩等),包括学生信息输入(添加)、学生信息浏览、学生总成绩计算和将学生信息存入文件。
其中第(7)为选作内容,如果学生能够做出来,实验成绩应给予加分奖励。 (二)程序总体设计
1、数据结构
依据给定的学生信息和数据类型,定义相应的数组和结构体类型分别如下: 课程名称定义为全局数组:
char course[Nmax][50] = {"Chinese","Mathematic","English"}; 学生结构体类型如下: struct student { };
以下的数组或变量均为局部类型的(可放在main函数中加以定义): sno数组存储学生学号,可事先加入初始数据若干条:
char
sno[Mmax][11]={"2011023001","2011023002","2011023003","2011023004"};
name数组存储学生姓名,可事先加入初始数据若干条; namesearch数组
用于存储要查找的学生姓名:
char name[Mmax][20]={"Zhang","Li","Cheng","Wang"}, namesearch[20]; 入初始数据若干条; avecourse数组存储每门课程的平均分,实际计算时可事先初始化:
float score[Mmax][Nmax]={ {73.5,85,67}, {83,91.5,87},{65, 82, float avecourse[Nmax]={0}; tscore数组存储每位学生成绩的总分:
char
code[11];
/* 学号 */
char name[20]; /* 姓名 */ float score[Nmax]; /* 各课程成绩 */ float total;
/* 总分 */
struct student *next;
score数组存储学生成绩;假设至多有M名学生,N门课程,可事先加
78},{71,83,80.5}};
铜陵学院 班级成绩管理系统的设计与实现 只需添加名字 学号
float tscore[Mmax]={0};
组中的名次(即index[0]存放了总分第一的学生在tscore数组中的下标, index[1]存放了总分第二的学生在tscore数组中的下标,依次类推):
index数组为排名索引(约定为降序),存储每位学生总成绩在tscore 数
int index[Mmax]; 录情况加以适时修改: int M=4, N=3;
M为实际学生数; N为实际课程数; M、N的值要根据插入或删除学生记
2、模块划分
依据程序的数据结构和功能,遵照“自顶向下”原则,采用基于函数的逐步求精法,描述该程序的层次结构。该程序可按给定的程序功能直接描述模块层次结构。该程序要求保留一种排序状态:按总分排序。
图1 模块层次结构
铜陵学院 班级成绩管理系统的设计与实现 只需添加名字 学号
在C语言中,模块用函数实现,函数原型清单如下(注意:以下各函数原型中很多地方用到了指向一维数组的指针变量或指向二维数组的指针变量,也可以将之对应的定义为形参数组的形式进行处理):
1-1 计算所有课程的平均分
void averagemark(float (*pscore)[Nmax], float *pavecourse, int m, int n) 1-2 计算每位学生所修课程总分
void totalmark(float (*pscore)[Nmax], float *ptscore, int m, int n) 1-3 按姓名查找学生记录
int retrievebyn(char (*pname)[20], char *pnamesearch, int m) 1-4 浏览全部学生信息
void displaystu(char (*psno)[11], char (*pname)[20], float (*pscore)[Nmax], float *ptscore, int m, int n)
1-5 按总分降序浏览全部学生信息
void displaystusort(char (*psno)[11], char (*pname)[20], float (*pscore)[Nmax],
float *ptscore, int *pindex, int m, int n)
1-6 添加新的学生记录
void insert(char (*psno)[11], char (*pname)[20], float (*pscore)[Nmax], float *ptscore, int *pm, int n)
1-7 用单链表进行班级成绩管理 void linkprocess() 2-1 按总分递减排序
void sortscore(float *ptscore, int *pindex, int m) 2-2 输入和添加学生信息
struct student *appendstuinfo(struct student *head) 2-3 浏览学生信息
void displaylist(struct student *head) 2-4 保存学生信息
void savestuinfo(struct student *head)
模块层次结构只是确定模块之间的关系和函数原型,不是程序的执行步骤。程序总体框架是该程序的总体流程图。该程序不是顺序执行全部功能,而是在某一时刻有选择地执行一种或多种功能。因此,选用菜单方式是较佳的方案。 三、小组各成员分工协作情况说明
铜陵学院 班级成绩管理系统的设计与实现 只需添加名字 学号
成员:负责编写的函数是: 成员:负责编写的函数是: 成员:负责编写的函数是: 四、编程体会(或是对实验系统做进一步改进的思考) 1)在进行编程时,要加强对结构体和指针变量的理解。 2始终要遵循先定义后使用的原则。 3在进行分组编程时,要注重组员间的配合。
4对于各个成员间所编的程序进行整合时要注意各个程序间要能正确连接和翻译。
五、程序代码
以下给出了程序的基本框架,请完成函数的功能及函数调用等程序代码的编写工作。 #include <stdlib.h> #include <string.h> #include <malloc.h> #include <stdio.h>
#define Mmax 120 /*记录最大学生数*/
#define Nmax 3 /*记录学生选课最大课程数目*/
char course[Nmax][50] = {"Chinese","Mathematic","English"};//以全局变量的形式给出各门课程的名称
/*当使用单链表进行班级成绩管理时,使用如下的结构体类型*/ struct student { };
char
code[11];
char name[20]; /* 姓名 */
float score[Nmax]; /* 各课程成绩 */ float total;
/* 总分 */
struct student *next;
铜陵学院 班级成绩管理系统的设计与实现 只需添加名字 学号
/*以下是各函数的声明,其中下面的7个函数和main函数是首先要实现的*/ void averagemark(float (*pscore)[Nmax], float *pavecourse, int m, int n); void totalmark(float (*pscore)[Nmax], float *ptscore, int m, int n); int retrievebyn(char (*pname)[20], char *pnamesearch, int m);
void displaystu(char (*psno)[11], char (*pname)[20], float (*pscore)[Nmax], float *ptscore, int m, int n);
void displaystusort(char (*psno)[11], char (*pname)[20], float (*pscore)[Nmax], float *ptscore, int *pindex, int m, int n);
void insert(char (*psno)[11], char (*pname)[20], float (*pscore)[Nmax], float *ptscore, int *pm, int n);
void sortscore(float *ptscore, int *pindex, int m);
/*以下各函数是用单链表进行班级成绩管理时,需要用到函数。实际编程时,先实现以上的7个函数及main函数,而对下面4个函数在具体编程时,可只给出相应空函数形式,等真正要实现时,再具体编写它们*/ void linkprocess();/*这是函数的声明*/
struct student *appendstuinfo(struct student *head); void displaylist(struct student *head); void savestuinfo(struct student *head);
/*下面是main函数,但需要你完善函数的调用;如果变量不够用,请自行添加*/
void main() {
/*sno数组存储学生学号,可事先加入初始数据若干条*/ char
/*name数组存储学生姓名; namesearch数组用于存储要查找的学生姓名*/ char name[Mmax][20]={"Zhang","Li","Cheng","Wang"}, namesearch[20]; /*score数组存储学生成绩;avecourse数组存储每门课程的平均分,实际计float score[Mmax][Nmax]={ {73.5,85,67}, {83,91.5,87},{65, 82, /*tscore数组存储每位学生成绩的总分*/ float tscore[Mmax]={0};
sno[Mmax][11]={"2011023001","2011023002","2011023003","2011023004"};
算时要初始化*/
78},{71,83,80.5}}, avecourse[Nmax]={0};
铜陵学院 班级成绩管理系统的设计与实现 只需添加名字 学号
/*index数组为排名索引(约定为降序)*/ int index[Mmax];
int M=4, N=3; /* M为实际学生数; N为实际课程数; M、N的值可根据情int i,j; char c; while(1) {
system("cls");/*清屏操作*/
printf("\n\t 这是班级成绩管理系统,请选择你要的操作:\n\n"); printf("\t\t 1 : 计算所有课程的平均分\n");
printf("\t\t 2 : 计算每位学生所修各门课程的总分\n"); printf("\t\t 3 : 按姓名查找学生记录\n"); printf("\t\t 4 : 浏览全部学生信息\n");
printf("\t\t 5 : 按总分降序浏览全部学生信息\n"); printf("\t\t 6 : 添加(插入)新的学生记录\n"); printf("\t\t 7 : 用单链表进行班级成绩管理\n"); printf("\t\t 8 : 退出系统!\n"); printf("\n\n请输入命令: "); scanf("%c",&c); if(c=='8') { } switch(c) {
case '1': /* 计算课程平均分 */
调用averagemark函数,计printf("\n");
for(j=0;j<N;j++)/*显示每门课程的平均分*/
printf("%s课程的平均分是: %.2f.\n", course[j], avecourse[j] ); getchar();
况修改;由赋初值情况知M=4,N=3*/
/* 输入选择命令 */
puts("\n 谢谢使用!"); break;
/* 结束程序运行 */
算课程的平均分 */
铜陵学院 班级成绩管理系统的设计与实现 只需添加名字 学号
getchar(); break;
调用totalmark函数,计算每位printf("\n");
for(i=0;i<M;i++)/*显示每位学生的总分*/
printf("第%d名学生的总分是: %.2f.\n", i+1, tscore[i]); getchar(); getchar(); break;
printf("请输入你想查找的学生姓名: "); scanf("%s",namesearch);
调用retrievebyn函数 */ if(i==-1) { }
getchar(); getchar(); break;
printf("\n你查找的学生记录是:\n");
printf("学号: %s\n姓名: %s\n",sno[i], namesearch); for(j=0;j<N;j++)/*显示每门课程成绩*/
printf("%s课程成绩是: %.2f.\n", course[j], score[i][j] ); printf("所修课程总分是:%.2f.\n", tscore[i]); printf("学生%s不存在.\n", namesearch); else
case '2': /* 计算每位学生总分 */
学生总分 */
case '3': /* 按学生的姓名寻找记录 */
case '4': /* 浏览全部学生信息(包括学号、姓名、各门功课成绩和总调用displaystu函数 */
getchar(); getchar(); break;
成绩) */
case '5': /* 按总分降序浏览全部学生信息(包括学号、姓名、各门功
课成绩和总成绩) */
铜陵学院 班级成绩管理系统的设计与实现 只需添加名字 学号
}
}
}
调用getchar();getchar(); break;
调用insert函数 */ getchar();getchar(); break;
displaystusort函数 */
case '6': /*添加(插入)新的学生记录*/
case '7': /*用单链表处理班级学生信息*/ 调用linkprocess函数 */
getchar(); getchar(); break;
printf("\n\n输入的命令不对,请重新输入!!\n"); getchar(); getchar(); break;
default:
/*下面请你编写各功能模块对应的函数*/
/*下面linkprocess 函数是先用空函数实现的实例,它是利用单链表进行班级成绩管理时,需要用到函数,该函数会调用appendstuinfo、displaylist、savestuinfo三个函数,等真正实现时,删掉以下linkprocess空函数对应的两行代码,再具体编写此四个函数*/
void linkprocess()/*这是空函数*/ {}
/*下面请你编写函数声明中的前7个函数*/
#include <string.h> #include <malloc.h> #include <stdio.h>
#define Mmax 120 /*记录最大学生数*/
#define Nmax 3 /*记录学生选课最大课程数目*/
铜陵学院 班级成绩管理系统的设计与实现 只需添加名字 学号
char course[Nmax][50] = {"Chinese","Mathematic","English"};//以全局变量的形式给出各门课程的名称
/***********************************************************************************************************/ /*这是用单链表进行班级成绩管理*/
/*用单链表(结构体)处理班级学生信息(学号、姓名、成绩等),包括学生信息输入、学生信息浏览、学生总成绩计算和将学生信息存入文件*/ struct student {
char
code[11];
/* 假设学号有10位数字(注意此时要求存储空间要11
个字节),例如2011023102表示入学年份为2011年,023是专业编码,102是学生在班级中的排号*/ };
/* 输入和添加学生信息 */
/*采用链表首部添加方法,即让head指向的第一个结点放在新结点之后,而让新结点作为head的第一个结点*/
/*在输入新数据的同时,计算学生总成绩*/ struct student *appendstuinfo(struct student *head) {
char c; int j;
struct student *p; do {
p=(struct student *)malloc(sizeof(struct student)); printf("\n请输入学生信息\n\n"); printf( "请输入学号:" ); scanf( "%s", p->code ); printf( "请输入姓名:" ); scanf( "%s", p->name ); p->total=0;/*总成绩置零*/
char name[20]; /* 姓名 */
float score[Nmax]; /* 各课程成绩 */ float total;
/* 总分 */
struct student *next;
铜陵学院 班级成绩管理系统的设计与实现 只需添加名字 学号
}
for( j=0; j<Nmax ; j++ )/*输入每门课程成绩*/ { }
/*新结点p插入到链表首部*/ p->next=head; head=p;
getchar();//排除多余的输入
printf("是否还要继续输入学生数据(Y :需要,N:停止输入):"); scanf("%c", &c);
printf( "请输入%s成绩:", course[j] ); scanf( "%f", &(p->score[j]) ); p->total += p->score[j];
}while(c == 'Y' || c == 'y'); return head;
/*浏览学生信息*/
void displaylist(struct student *head) { }
struct student *p; int j;
if(head == NULL) }
printf("\n所有学生记录如下:\n"); p=head; while(p) { }
printf("\n\n");
printf("学号: %s\n",p->code); printf("姓名: %s\n", p->name);
for( j=0; j<Nmax ; j++ )/*显示每门课程成绩*/
printf("%s成绩:%.2f\n", course[j], p->score[j]); printf("总成绩: %.2f\n", p->total); p=p->next;
铜陵学院 班级成绩管理系统的设计与实现 只需添加名字 学号
/* 保存学生信息(保存到文件stuinfo.txt) */ void savestuinfo(struct student *head) { }
/*下面是用单链表进行班级成绩管理子菜单程序*/ void linkprocess() {
char c;
struct student *head=NULL; getchar(); while(1) {
system("cls");/*清屏操作*/
printf("\n\t 这是班级成绩管理系统(用单链表处理),请选择你要的操作:FILE *fp; struct student *p; int j; p=head;
if( (fp=fopen("e:\\stuinfo.txt","w")) == NULL ) { } while(p) { }
printf("\n数据已经保存到文件stuinfo.txt中!\n"); fclose(fp);
fprintf(fp,"%s\n",p->code); fprintf(fp,"%s\n",p->name); for(j=0;j<Nmax;j++)
fprintf(fp,"%.2f\n",p->score[j]); fprintf(fp,"%.2f\n",p->total); p=p->next;
printf("不能打开stuinfo.txt文件\n"); exit(0);
\n\n");
铜陵学院 班级成绩管理系统的设计与实现 只需添加名字 学号
}
}
printf("\t\t 1 : 输入和添加学生信息\n"); printf("\t\t 2 : 浏览学生信息\n");
printf("\t\t 3 : 保存学生信息(保存到文件stuinfo.txt)\n"); printf("\t\t 4 : 回到上一级菜单!\n"); printf("\n\n请输入命令: "); scanf("%c",&c); if(c=='4') { } switch(c) { }
case '1': /* 输入和添加学生信息 */
head=appendstuinfo(head); getchar(); getchar(); break;
displaylist(head); getchar(); getchar(); break;
savestuinfo(head); getchar(); getchar(); break;
printf("\n\n输入的命令不对,请重新输入!!\n"); getchar(); break;
puts("\n 回到上一级菜单!"); break;
/* 5结束程序运行 */
/* 输入选择命令 */
case '2': /* 浏览学生信息 */
case '3': /* 保存学生信息(保存到文件stuinfo.txt) */
default:
铜陵学院 班级成绩管理系统的设计与实现 只需添加名字 学号
/*****************************以上是用单链表进行班级成绩管理子菜单程序**********************************/ /*下面函数完成所需要的学生成绩管理功能*/ /*averagemark函数功能是计算课程的平均分*/
void averagemark(float (*pscore)[Nmax], float *pavecourse, int m, int n) { }
/* totalmark函数功能是计算每位学生总分 */
void totalmark(float (*pscore)[Nmax], float *ptscore, int m, int n) { }
/*displaystu函数用于显示m名学生的信息;其形参中,pname指向学生姓名首地址,pscore指向学生成绩首地址,m表示要输出的学生数,n表示要输出的课程数*/
void displaystu(char (*psno)[11], char (*pname)[20], float (*pscore)[Nmax], float *ptscore, int m, int n) {
int i,j;
printf("\n共有%d条学生记录, 分别如下:\n",m); for( i=0; i<m; i++ ) {
printf("\n");
int i,j;
for( j=0; j<n; j++ )/*初始化*/
*(pavecourse+j) = 0; for( i=0; i<m; i++ )
*(pavecourse+j) += *(*(pscore+i)+j);
for( j=0; j<n; j++ )
for( j=0; j<n; j++ )/*平均分*/
*(pavecourse+j) /=m;
int i,j;
for(i=0; i<m; i++)/*初始化*/
*(ptscore+i) = 0; for( j=0; j<n; j++ )
*(ptscore+i) += *(*(pscore+i)+j);
for( i=0; i<m; i++ )
铜陵学院 班级成绩管理系统的设计与实现 只需添加名字 学号
}
}
printf("姓名: %s\n", pname[i]);
for( j=0; j<n ; j++ )/*显示每门课程成绩*/
printf("%s的成绩是: %.2f.\n", course[j], pscore[i][j] ); printf("所修课程总分是:%.2f.\n", ptscore[i]);
/*sortscore函数功能是对学生总分进行排序(按降序),形成排名索引:方法一:下法用插入的方法;*/
/*方法二(用此方法比较好理解):先将ptscore数组存放在一个临时数组arr中, pindex初始化为0,1,...,m-1,然后同步与arr用选择法或者冒泡法排序*/ void sortscore(float *ptscore, int *pindex, int m) { }
/*displaystusort函数从高分到低分显示学生信息;其形参中,pname指向学生姓名首地址,pscore指向学生成绩首地址,m表示要输出的学生数,n表示要输出的课程数*/
/*pindex指向排名索引*/
void displaystusort(char (*psno)[11], char (*pname)[20], float (*pscore)[Nmax], float *ptscore, int *pindex, int m, int n) {
int i,j; int i, j; pindex[0]=0; for( i=1; i<m; i++ ) { }
for( j=i-1; j>=0; j-- ) { }
pindex[j+1] = i;
if( ptscore[i] > ptscore[pindex[j]])
pindex[j+1] = pindex[j]; break; else