C语言学生学习成绩管理系统实验报告
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
学生学习成绩管理系统
1.课程设计的目的
1.对于给定的设计题目,如何进行分析,理清思路,并给出相应的数学模型。
2.掌握自顶而下的设计方法,将大问题进行模块化,领会结构化程序设计的方法。
3.熟练掌握C语言的基本语法,灵活运用各种数据类型。
4.进一步掌握在集成环境下如何调试程序(单步调试,设置断点、观察表达式,分块调试)和修改程序。
2.课程设计的要求
1.程序在运行时,均以菜单形式提供选择界面,并提供一定的数据安全和提示具有良好的交互功能。
2.设计中的每一个小功能均由子函数来完成
3.提前编制下次调试的程序,对于难点问题要积极查阅相关教材、资料,计划好每次上机的内,高效、独立地完成这次设计任务
4.在硬盘上建立自己的目录,将程序文件存储到该目录下,即有利于调试文件,又保证了文件的安全性。
3.课程设计报告内容
3.1任务定义
本系统主要应用数据结构的设计思想,在TC环境下运用C语言进行编程设计一个学生成绩管理系统,该系统主要实现对学生的学号、姓名等自然信息以及学生成绩信息进行创建、增加、删除、查询、插入、显示的功能以及计算所有学生总成绩的总分,并依照学生各类信息高低进行排名的功能。
系统给用户提供了一个简单的人机界面,使用户可以根据提示输入操作项,调用系统提供的管理功能。
3.2系统运行环境
操作系统:Windows 98/2000/XP
运行软件:TC
3.3功能需求(问题分析)
学生成绩管理系统为教师和学生提供了一个对学生自然信息和学科成绩进行管理和查看的平台,给用户提供了一个简单友好的用户接口,功能需求分析描
述如下:
(1)编写菜单函数,为用户提供一个友好的操作选择界面。
(2)学生信息输入:用户根据提示输入学生的学号、姓名、各科成绩,可一次
性输入多条学生的成绩信息记录;当要停止输入并退回主菜单时,只须输入0符号回车即可。
(4)学生信息删除:提示用户输入要删除的学生学号或姓名,如果输入的学号
不存在,系统会立即提示不存在该学号的学生请先添加。
(6)学生信息添加(插入):使用户可以根据提示在原有的学生成绩表中的任何
位置添加新的学生信息记录。
(7)学生信息查询:根据系统提示输入要查找的学生名字或学号回车后,即可
显示已找到的学生信息记录。
(8)学生成绩计算:系统能够自动计算所有学生的总成绩。
(9)学生成绩排序:按照系统提示选择项目进行从高分到低分排序。
(10)学生信息清单显示:系统显示所有学生的信息情况,包括学生学号、姓名、各科成绩、个人总成绩。
(11)系统退出:实现用户退出本系统的功能。
3.4 程序设计步骤 1.大体结构图
2.主程序模块分析
整个系统功能共分八个功能:
1.addstudent 学生信息添加
2.editstudent学生信息修改
3.delstudent信息清单删除
4.showstudent学生信息排序
5.findstudent学生成绩查找
6.loadstudent载入文件信息
7.savestudent学生信息保存
0.exit系统退出
以上八个功能就是本系统模块的主要功能,根据需求分析,对其进行功能逻辑设计:
(1)定义数据结构typedef struct student{ ……}stu;。
以下分别要用到的函数为:菜单函数void showmenu()的函数,定位链表中符合要求的接点stu* Locate(stu *s,char find[],int k)用于插入和查找功能,删除记录函数status delstudent(stu *s),显示所有记录的函数void show(stu *s,int k),显示学号对应的姓名 void showid(stu *s)),排序函数status list(stu *s,int k),添加记录函数status addstudent(stu *s),查询函数status findstudent(stu *s) 载入文件信息status loadstudent(stu *s), 保存学生status savestudent(stu *s),关闭
exit(0);
(2)学生信息输入:实现可以输入学生的学号、姓名、各科成绩的功能。
首先定义指向结构体的指针,动态申请空间;用if(k == 0) break;实现当学号首字符为0则结束输入的功能;在for循环中嵌套while{}{},实现N门课程循环N 次和成绩正确输入,接着用到了数据结构的新结点插入的知识。
(3)学生信息删除:实现输入要删除的学生学号,执行后就可以删除该学生所有信息。
该功能用到status delstudent(stu *s)删除记录的函数,先定义p为查找到要删除的结点指针,如果还没信息则显示添加,函数返回到Locate,否则通过while(r->next != p) r = r->next; r->next = p->next; free(p);确定要删除的项目。
(4)学生信息清单显示:系统显示所有学生的信息情况,包括学生编号、学号、姓名、各科成绩、个人总成绩。
这里用到显示函数实现输出链表中结点信息的功能。
(5)学生信息查询:根据系统提示输入要查找的学生名字或学号回车后,即可以排列的形式显示已找到的学生信息记录,接着自动跳到主菜单。
用到status
findstudent(stu *s)查找函数。
(6)学生成绩计算:利用 allscore=mscore+escore+cscore求得.
(7)学生信息添加:直接用用addstudent函数添加。
(8)学生成绩排序:选择并执行该功能后,系统提示使按学号,各科成绩或总
成绩排列,选择后系统自动按降序排列。
(9)系统退出:实现用户退出本系统的功能。
其实这里只用到了一个exit(0);
3.5流程图
3.6详细设计
1.函数原型
void showmenu() 菜单函数
stu* Locate(stu *s,char find[],int k) /*结点添加(插入)*/
status delstudent(stu *s) /*删除记录*/
void show(stu *s,int k) /*显示所有记录的*/
void showid(stu *s) /*显示学号对应的姓名*/
status list(stu *s,int k) /*排序*/
status addstudent(stu *s) /*添加记录*/
status findstudent(stu *s) /*查询*/
status loadstudent(stu *s) /*载入文件信息*/
status savestudent(stu *s) /*保存学生*/
exit(0); /*关闭*/
2.计算公式
allscore=mscore+escore+cscore
3.定义数据结构
用一个类的嵌套定义struct student *next;用整型数据定义学号和成绩,用char定义姓名。
typedef struct student{
int num; // 学号
char name[20]; // 姓名
int mscore; // 数学成绩
int cscore; // c语言成绩
int escore; // 英语成绩
struct student *next;//嵌套定义结构体指针
}stu;
3.7.函数说明(算法分析)
(1)链表定义头指针stu *s,初始化链表s->next=NULL;,主函数调用set,set 值作为开关语句的条件,switch函数中用了八个case:
case 1:addstudent(s);break; // 增加学生
case 2:editstudent(s);break;// 修改学生
case 3:delstudent(s);break;// 删除学生
case 4:showstudent(s);break;//查看学生信息
case 5:findstudent(s);break;// 查询学生
case 6:loadstudent(s);break;//载入文件信息
case 7:savestudent(s);break;// 保存学生
default: getchar();break;//关闭系统
(2)菜单函数
定义菜单字符串数组,以字符形式保存选择号,定义整形变量作为开关的条件,要求输入选择项,利用开关定义当输入值超过7直接返回到主菜单重新选择输入,主程序根据该数调用相应的函数。
实现了菜单美观和简便效果。
(3)链表
定义stu指向结构体的指针,并使用类嵌套定义类对象struct student *next,定义*s->next为头链表头依次往下输出信息知道指针指到的某个对象为
空时停止并返回主菜单选择。
直接在输出数值时添加mscore+escore+cscore作为总成绩加到信息最后一列。
(4)show函数
为了能让用户输入字符串,依然是定义一个开关,此时的开关条件无最大值,添加信息时直接调用show函数即可实现学生信息的输入。
(5)printf函数
编写显示函数用来输出链表中结点信息, stu型指针r,接着r=*s初值为头指针,用printf方法输出存储学生信息,最while(r!=NULL){……}实现当表中有信息即不为空,就执行while中的内容,打印出学生的各个信息。
(6)delete函数
用来删除记录,先用if(!s->next) {printf("has no student!\nplease add at frist!")验证学生信息是否为空,如果为空则输出“please add first”。
如果不为空,先选择按学号删除或按姓名删除,然后调用函数stu* Locate(stu *s,char find[],int k)查找要删除的记录。
然后用freep()执行记录清空。
(7)insert函数
用来插入学生记录,定义二个指针为p和l,l为前驱,p为插入数据的位置。
如果遇到相同学号的则显示输入有重复并显示原来学号的信息。
如不然则用scnf和printf输入输出数据,并在运行结束后把指针置尾。
(8)sort函数
根据不同的要求实现成绩从大到小排列,程序中采用的使选择法进行排序,排序过程中调用swap函数实现数据的排列。
这样就能按不同要求把数据排列了。
3.8程序调试与测试(结果分析)
1.函数主界面
2.选择第一项实现添加数据如下
3.选择2进行修改编辑
4.选择3进行删除成绩
5.选择4进行排序显示成绩
6.选择5进行查找成绩
7.选择6提供载入信息条数
8.选择7保存
9.选择0关闭
要保存选Y不想保存先N。
结果分析
程序运用了结构体,链表,转换和选择法排序实现了删除,添加,信息载入,查询等功能。
(1)单链表查找算法的最好的时间复杂度为o(1),最坏时间复杂度o(n),平均时间复杂度o(n);空间复杂度为o(1)。
(2)单链表插入算法时间复杂度o(n);空间复杂度为o(1)。
(3)系统基本上实现了小型学生管理系统的功能。
4.总结
C语言使上学期教的,现在开始做这个课程设计刚开始有点仿偟,不知道何从下手,最后搬出书本有看了一下,网上查点资料,仔细阅读老师给的任务指导书,开始着手做这个学生成绩管理系统,其原因使该算法简便,程序贴近学生生活,该程序的目的使实现学生成绩的粗略管理。
设计过程经过了任务定义,逻辑设计、详细设计、程序编码、程序调试与测试、结果分析和撰写实验报告,最终系统地完成整个课程的设计。
该系统是小型管理系统,运行界面为DOS界面,始终存在不足,从这次设计
中我深刻的体会C设计的意义,我觉得编程除了麻烦也是一件有趣的事情。
参考文献
[1]谭浩强.C程序设计[M]北京:清华大学出版社, 2005.292页-310页.
[2] 苏仕华. 数据结构课程设计[M].上海:机械工业出版社,2004.
[3] 谭浩强.C程序设计题解与上机指导[M]北京:清华大学出版社,2005.
附录
#include<stdio.h>
#include<stdlib.h>//提供malloc()、calloc()、realloc()、free()、system()、atoi()、atol()、rand()、
srand()、exit()/
#include<string.h>//字符串调用
typedef int status;
int change = 0; // 信息是否改变
typedef struct student{
int num; // 学号
char name[20]; // 姓名
int mscore; // 数学成绩
int cscore; // c语言成绩
int escore; // 英语成绩
struct student *next;//定义指针
}stu;//定义对象stu
void showmenu(){
printf("\n\t\t***list of student***");
printf("\n\t\t* *");
printf("\n\t\t* 1:addstudent *");
printf("\n\t\t* 2:editstudent *");
printf("\n\t\t* 3:delstudent *");
printf("\n\t\t* 4:showstudent *");
printf("\n\t\t* 5:findstudent *");
printf("\n\t\t* 6:loadstudent *");
printf("\n\t\t* 7:savestudent *");
printf("\n\t\t* 0:exit *");
printf("\n\t\t* *");
printf("\n\t\t*********************\n");
} //给出菜单选择
void show(stu *s,int k){ // 用指向StU对象的指针输出学生信息
switch(k){
case 0:printf("num name mscore cscore escore allscore\n");break;
case 1:
printf("num name mscore cscore escore allscore\n");
printf("%3d%-8s %6d %6d %6d %6d\n",s->num,s->name,s->mscore, s->cscore,s->escore,(s->mscore+s->cscore+s->escore));
break;
default:
printf("%3d%-8s %6d %6d %6d %6d\n",s->num,s->name,s->mscore, s->cscore,s->escore,(s->mscore+s->cscore+s->escore));
break;
}
}
void showid(stu *s){// 显示学生学号对应的姓名
while(s->next){
s = s->next;
printf("%3d:%-8s ",s->num,s->name);
}
}
stu* Locate(stu *s,char find[],int k){ // 该函数用于定位连表中符合要求的接点,
返回该指针
stu *r;
if(strcmp(find,"num") == 0){ // 按学号查询
r = s->next;
while(r != NULL){
if(r->num == k) return r;
r = r->next;
}}
else if(k == 0){ // 按姓名查询
r = s->next;
while(r != NULL){
if(strcmp(r->name,find) == 0) return r;
r = r->next;}
}
return 0;
}
status _swap(stu *s1,stu *s2){//把一个对象的学生数据赋给另一个学生s1->num = s2->num; //学号
strcpy(s1->name,s2->name); //姓名
s1->mscore = s2->mscore; // 数学成绩
s1->cscore = s2->cscore; //c语言成绩
s1->escore = s2->escore; //英语成绩
}
status swap(stu *s1,stu *s2){//实现两个学生信息的转换
stu *p;
if(!(p = (stu *)malloc(sizeof(stu)))) showerror(0);
_swap(p,s1);
_swap(s1,s2);
_swap(s2,p);
free(p);//释放p所占的空间
}
status list(stu *s,int k){//采用选择法排序
stu *p,*p1,*p2;
p1 = s->next;
while(p1){
p2 = p1->next;
while(p2){
if(k == 1)if(p2->num < p1->num)swap(p1,p2); //学号
if(k == 2)if(p2->mscore > p1->mscore)swap(p1,p2);
if(k == 3)if(p2->cscore > p1->cscore)swap(p1,p2); //c成绩
if(k == 4)if(p2->escore > p1->escore)swap(p1,p2); //英语成绩
if(k==5)if((p2->mscore+p2->cscore+p2->escore;> (p1->mscore+p1->cscore+p1->escore))swap(p1,p2); //总分
p2=p2->next;
}
p1=p1->next;
}
;}
status eshow(stu *s){
show(s,0);
while(s->next){
s = s->next;
show(s,2); }}
status addstudent(stu *s){
stu *p,*l;
int k;
while(1){
l = s;
printf("please input num[0:return]:");
scanf("%d",&k);
if(k == 0) break;
while(l){
if((l->num) == k){
printf("the '%d' student is Repeated!\n",k);
show(l,1);
return;
}
l = l->next;
}
if(!(p = (stu *)malloc(sizeof(stu)))) showerror(0);
printf("input %d student:name,mscore,cscore,escore like[lucy 80 80 80]:",k);
scanf("%s%d%d%d",&p->name,&p->mscore,&p->cscore,&p->escore);
p->num = k;
p->next = NULL;
if(s ==NULL) s = p;
else{
while(s->next != NULL) s = s->next;// 将指针置于最末尾
s->next = p;
}
p = NULL;
change=1;
}
}
status editstudent(stu *s){// 修改学生
int k=0;
while(k == 0){
printf("\nplease input edit num[0:show all]:");
scanf("%d",&k);
if(k == 0) showid(s);
}
while(s){
if((s->num) == k){
printf("\ninput [%d %s %d %d %d]
student:name,mscore,cscore,escore:",k,s->name,s->mscore,s->cscore,s->escore); scanf("%s%d%d%d",&s->name,&s->mscore,&s->cscore,&s->escore);
change=1;
printf("\nfinish!\n");
return;
}
s = s->next;
if(!s) printf("=====>the student '%d'is not find!\n",k); }
}
status delstudent(stu *s){// 删除学生
int set,k;
stu *p,*r;
char find[20];
if(!s->next) {
printf("has no student!\nplease add at frist!");
}
printf("\n=====>1del with num\n=====>2del with name\n");
scanf("%d",&set);
if(set == 1){
printf("please input the num :");
scanf("%d",&k);
p = Locate(s,"num",k);
}
else if(set == 2){
printf("input the name:");
scanf("%s",find);
p=Locate(s,find,0);
}
else {
printf("input error!");
//return;123456
}
if(p){
r = s;
while(r->next != p) r = r->next;
r->next = p->next;
free(p);
printf("\n=====>finish!\n");
change = 1;
}
else{
printf("no find!");
//return;123456
}
}
status showstudent(stu *s){// 查看学生信息
int k=0;
while(k<1||k>5){
printf("order by [ 1 num, 2 mscore, 3 cscore, 4 escore, 5 allscore]"); scanf("%d",&k);
list(s,k);
eshow(s);
//return;123456
}
}
status findstudent(stu *s){// 查询学生
int set,k;
stu *p,*r;
char find[20];
if(!s->next) {
printf("has no student!\nplease add at frist!");
return;
}
printf("\n=====>1del with num\n=====>2del with name\n"); scanf("%d",&set);
if(set == 1){
printf("please input the num :");
scanf("%d",&k);
p = Locate(s,"num",k);
}
else if(set == 2){
printf("input the name:");
scanf("%s",find);
p=Locate(s,find,0);
}
else {
printf("input error!");
//return;123456
}
if(p) show(p,1);
else{
printf("no find!");
//return;123456
}
}
status loadstudent(stu *s){// 载入文件信息
stu *r;
FILE *fp; // 文件指针
int count = 0;
char jian;
fp = fopen("student.stu","rb");
if(fp == NULL){
printf("\ndate file is not find,buding?(y/n)\n");
scanf("%c",&jian);
if(jian == 'y'||jian == 'Y') fp = fopen("student.stu","wb"); else showerror(1);
}
printf("\n=====>file is find,opening...\n");
while(!feof(fp)) {
r = (stu *)malloc(sizeof(stu));
if(fread(r,sizeof(stu),1,fp)){ // 将文件的内容放入接点中
r->next = NULL;
s->next = r;
s = r; // 将该接点挂入链中
count++;
}
}
fclose(fp); // 关闭文件
printf("\n=====>filish,%d report is found.\n",count);
}
status savestudent(stu *s){// 保存学生
FILE* fp;
stu *p;
int flag = 1,count = 0;
fp=fopen("student.stu","wb");
if(fp == NULL) showerror(1);
p = s->next;
while(p){
if(fwrite(p,sizeof(stu),1,fp) == 1){
p = p->next;
count++;
}
else{
flag = 0;
break;
}
}
if(flag){
printf("\n=====>finish.(%d report is saved.)\n",count);
change = 0;
}
fclose(fp);
}
status showerror(int k){
switch(k){
case 0:printf("\nMemory Failure!\nplease any key exit!");getch();exit(0);break;
case 1:printf("\nfile error!\nplease any key exit!");getch();exit(0);break;
default:getchar();break;
}
}
void main(){
stu *s;// 链表
int set;
char ch;
s=(stu *)malloc(sizeof(stu));
s->next=NULL;
loadstudent(s);
// while(1){
showmenu();
while(1){printf("\n");
printf("please input the menu:");
scanf("%d",&set);
if(set == 0){
if(change == 1){
getchar();
printf("\n=====>the dat is changed,save?(y/n)?\n"); scanf("%c",&ch);
if(ch=='y'||ch=='Y')
savestudent(s);
}
break;
}
switch(set){
case 1:addstudent(s);break; // 增加学生
case 2:editstudent(s);break;// 修改学生
case 3:delstudent(s);break;// 删除学生
case 4:showstudent(s);break;//查看学生信息
case 5:findstudent(s);break;// 查询学生
case 6:loadstudent(s);break;//载入文件信息
case 7:savestudent(s);break;// 保存学生
default: getchar();break;//直接返回到主菜单的选择界面
}
}
}。