基本要求:
1、实现一个简易的成绩系统;
2、每个学生结点包括学号、姓名和3门课程的成绩,要求:
(1)输入若干学生的信息,并存入文件中;
(2)从文件中读取信息构建链表,并显示信息;
(3)根据学号删除指定的学生结点;
(4)插入给定的学生结点;
(5)对学生求平均分;
(6)求课程的最高分和最低分。
3、要求采用模块化设计,独立的功能应在各个自定义函数中实现。数据加载保存可以考虑文件。
一、结构体说明
typedef struct node //结构体类型 node(链表)
{
int id; //学生学号
char name[10]; //学生姓名
int score[3]; //学生三门课的成绩
struct node *next; //下一连接点地址
}STU; //取别名STU
typedef struct node SNODE;
STU s[N],st; //定义结构体变量数组s[N]与结构体变量st
二 、函数列表及介绍
SNODE *creat() ; //用于创建链表,将文件的数据存入链表中
void print(SNODE *head) ; //用于输出链表数据
void input(); //向文件输入信息
SNODE *del(SNODE *head,int id); //删除函数,删除某指定的学生数据
SNODE *insert(SNODE *head); //插入函数,在指定学号前插入学生数据
void average(SNODE *head); //依次求每个人的平均分
void search(SNODE *head); //求三门成绩各科的最高分和最低分
三 、源程序
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define N 5 //学生人数为5人,可更新
typedef struct node //定义结构体类型
{
int id;
char name[10];
int score[3];
struct node *next;
}STU;
typedef struct node SNODE;
SNODE s[N],st; //定义结构体变量
SNODE *creat() ; //函数列表,具体功能在“二”中介绍
void print(SNODE *head) ;
void input();
SNODE *del(SNODE *head,int id);
SNODE *insert(SNODE *head);
void average(SNODE *head);
void search(SNODE *head);
int main()
{
int choice,number;
SNODE *head;
printf("----学生成绩系统----\n");
while(1) //在屏幕上输出菜单
{
printf("\n1.输入信息 \n2.信息存入链表 \n3.读取信息 \n4.删除数据 \n5.插入数据 \n6.计算学生平均分 \n7.求课程最高分和最低分 \n0.退出\n");
printf("please input your choice\n");
scanf("%d",&choice); //输入用户选择
switch(choice) //八个数字对应不同功能
{
case 1:input();break;
case 2:head=creat();break;
case 3: printf("现有信息为:\n");
print(head); //输出链表信息
break;
case 4:printf("输入你要删除的学号\n");
scanf("%d",&number);
head=del(head,number);
printf("现有信息为:\n");
print(head);break;
case 5:head=insert(head);
break;
case 6: printf("每位同学的平均分为:\n");
average(head);
break;
case 7:printf("各科目最高分和最低分为\n");
search(head);
break;
case 0:goto end;break; //用goto语句导至 end。退出循环,结束程序
}
}
end:return 0;
}
SNODE *creat() //创建链表的函数,将数据从文件导入链表
{
FILE *fp;
SNODE *h,*s,*r;
h=(SNODE*)malloc(sizeof(SNODE));
r=h;
int i;
if((fp=fopen("C:\\student.dat","rb"))==NULL)
{
printf("cannot open this file!\n"); //打开文件失败的提示
exit(0);
}
for(i=0;i<N;i++)
{
fread(&st,sizeof(STU),1,fp); //读取文件中的信息
s=(SNODE*)malloc(sizeof(SNODE)); //将结构变量数组中的数据挂上链表
s->id=st.id; strcpy(s->name,st.name); s->score[0]=st.score[0]; s->score[1]=st.score[1]; s->score[2]=st.score[2];
r->next=s;
r=s;
}
r->next='\0';
return h;
}
void print(SNODE *head) //输出链表的函数
{SNODE *p;
p=head->next;
if(p==NULL) printf("\nLinkList is NULL!\n");
else{
do{ printf("%-10d%-11s%6d%6d%6d\n",p->id,p->name,p->score[0],p->score[1],p->score[2]);
p=p->next;
}while(p!=NULL);
}
}
void input()
{
FILE *fp;
int i;
if((fp=fopen("C:\\student.dat","wb"))==NULL)
{
printf("cannot open this file!\n");
exit(0);
}
for(i=0;i<N;i++)
{
printf("input \nstudent %d information\n",i+1);
printf("id:");
scanf("%d",&s[i].id);
printf("name:");
scanf("%s",s[i].name);
printf("3 score:");
scanf("%d%d%d",&s[i].score[0],&s[i].score[1],&s[i].score[2]);
}
fwrite(s,sizeof(STU),N,fp);
fclose(fp);
printf("input voer\n");
}
SNODE *del(SNODE *head,int id) //以学号为线索删除指定数据
{
SNODE *p1,*p2;
p1=head;
while(id!=p1->id&&p1->next!=NULL)
{p2=p1; p1=p1->next;}
if(id==p1->id) //找到需删除的学号信息
{
if(p1==head) head=p1->next;
else
p2->next=p1->next;
printf("删除学号:%d 成功!可选择'3'以查看\n",id);
}
else printf("找不到学号:%d\n",id);
return(head);
}
SNODE *insert(SNODE *head) //插入函数,在指定学好前插入一个学生数据
{
SNODE *s,*p1,*p2;
char name[10];
int x,y,a[3],id;
s=(SNODE*)malloc(sizeof(SNODE));
printf("请输入要插入的结点 学号 姓名 三门成绩\n");
scanf("%d%s%d%d%d",&id,name,&a[0],&a[1],&a[2]);
s->id=y; strcpy(s->name,name); s->score[0]=a[0]; s->score[1]=a[1]; s->score[2]=a[2];
printf("要插入在什么学号之前\n");
scanf("%d",&x); //输入插入在某学号之前
p1=head; p2=head->next;
while((p2!='\0')&&(p2->id!=x))
{
p1=p2;
p2=p2->next;
}
s->next=p2; p1->next=s;
printf("插入成功!可选择'3'以查看\n");
return(head);
}
void average(SNODE *head) //求取每个学生三门课的平均分数
{SNODE *p;
p=head->next;
if(p==NULL) printf("\nLinkList is NULL!\n");
else{
do{
printf("%-10d%-11s%6.2f\n",p->id,p->name,(p->score[0]+p->score[1]+p->score[2])/3.0);
p=p->next;
}while(p!=NULL);
}
}
void search(SNODE *head) //找出三门课每一门的最高分和最低分
{SNODE *p;
int max[3]={0},min[3]={100,100,100}; //用数组存放三门课的分数并不断更新
int i=0;
p=head->next;
if(p==NULL) printf("\nLinkList is NULL!\n");
else{
do{
for(i=0;i<3;i++)
{if(max[i]<p->score[i])
max[i]=p->score[i];
if(min[i]>p->score[i])
min[i]=p->score[i];
}
p=p->next;
}while(p!=NULL);
}
for(i=0;i<3;i++)
printf("第%d科的最高分和最低分依次为 %d %d\n",i+1,max[i],min[i]);
}
四、程序运行结果
开始菜单界面
读取现有信息
删除某个数据
插入某项数据
求平均分(保留二位小数)
求各科最高分和最低分
五、说明
采用了文件和链表的形式。链表在进行插入,删除等功能时更为便捷,可以通过改变next地址值的办法从而更好地实现功能。而文件可以保存数据,不必每次使用都重新输入,大大提高了该小程序的实用性和功能性。
六、总结
这是我独立完成的一个完整的应用任务,实际代码量大约有110行,包含了6个核心功能,分别是:
(1)输入若干学生的信息,并存入文件中;
(2)从文件中读取信息构建链表,并显示信息;
(3)根据学号删除指定的学生结点;
(4)插入给定的学生结点;
(5)对学生求平均分;
(6)求课程的最高分和最低分,符合课程设计的要求。
我运用了数组、循环、随机数、判断、指针、链表、文件等多个C语言编程知识,许多无意识的小错漏,很多时候会影响程序的运行。因此,编写代码时的格式应该尤为注意,只有当界面整洁明了,寻找错漏处、修改代码时才会不那么费时费力,也让检查变得更加便捷简单。另外我其实认为本次程序还是有些欠缺。因为编程水平并不高,很多错误可能没有自检发现。如有其他多余错漏之处,望请批评指正。