Download - 第十二章 上机实训
第十二章 上机实训学习目标学习目标::通过一个完整实例让学生掌握通过一个完整实例让学生掌握 CC 语语言编程的知识言编程的知识,,提高综合分析和解决提高综合分析和解决问题的能力问题的能力。。
第三十二讲 学生成绩管理系统第三十二讲 学生成绩管理系统一、问题描述一、问题描述设计一个学生管理系统。该系统可以建立学生信息表,设计一个学生管理系统。该系统可以建立学生信息表,
向表中插入新记录,删除某记录,或在表中查找某特向表中插入新记录,删除某记录,或在表中查找某特定的学生信息。可输入一组学生成绩,包括每名学生定的学生信息。可输入一组学生成绩,包括每名学生的学号,姓名,语文、数学和英语成绩,建立学生成的学号,姓名,语文、数学和英语成绩,建立学生成绩信息表。可加入新学生信息到学生成绩表中,或删绩信息表。可加入新学生信息到学生成绩表中,或删除表中的某个位置的学生,或在表中查找某位置的学除表中的某个位置的学生,或在表中查找某位置的学生并将该学生的信息显示出来。在主函数中设计一个生并将该学生的信息显示出来。在主函数中设计一个菜单,将要进行的操作用菜单,将要进行的操作用 00 ~~ 44 来表示,允许用户输来表示,允许用户输入相应的数字来进行反复操作。入相应的数字来进行反复操作。
二、数据结构二、数据结构其主要的数据类型为带头结点的单链表:其主要的数据类型为带头结点的单链表:typedef struct nodetypedef struct node
{ int number; /*{ int number; /* 学生的学号学生的学号 */*/
char name[20]; /*char name[20]; /* 姓名姓名 */*/
int chinese,math,english; int chinese,math,english; /*/* 语文、数学和英语成绩语文、数学和英语成绩 */*/
struct node *next;struct node *next;
}LinkList;}LinkList;
三、程序流程三、程序流程11 .函数之间的调用关系图.函数之间的调用关系图程序流程图如图程序流程图如图 12-112-1 所示。所示。
22 .主要函数.主要函数(( 11 )初始化链表:)初始化链表: LinkList *InitList()LinkList *InitList() 。。(( 22 )求链表长度:)求链表长度: int Length_List(LinkList *H)int Length_List(LinkList *H) 。。(( 33 )建立链表函数:)建立链表函数: void CreateList(LinkList *H,int n)void CreateList(LinkList *H,int n)
。。(( 44 )表中元素定位函数:)表中元素定位函数: LinkList *Locate(LinkList LinkList *Locate(LinkList
*H,int num)*H,int num) 。。(( 55 )查找表中元素位置函数:)查找表中元素位置函数: LinkList *GetList(LinkList LinkList *GetList(LinkList
*H,int i)*H,int i) 。。(( 66 )在链表中插入新元素函数:)在链表中插入新元素函数: int InsList(LinkList int InsList(LinkList
*p,LinkList x)*p,LinkList x) 。。(( 77 )在给定位置)在给定位置 ii 插入元素函数:插入元素函数: int Ins_List(LinkList int Ins_List(LinkList
*H, int i, LinkList x)*H, int i, LinkList x) 。。
(( 88 )删除链表中的某元素函数:)删除链表中的某元素函数: int int DelList(LinkList *p,LinkList *x)DelList(LinkList *p,LinkList *x) 。。
(( 99 ))删除链表中给定位置的元素函数:删除链表中给定位置的元素函数: int int Del_List(LinkList *H,int i,LinkList *x)Del_List(LinkList *H,int i,LinkList *x) 。。
(( 1010 ))主函数中的菜单显示函数:主函数中的菜单显示函数: out()out() 。。(( 1111 ))输出表中信息函数:输出表中信息函数: void void
DisLinkList(LinkList *H)DisLinkList(LinkList *H) 。。(( 1212 ))主函数:主函数: main()main() 。。
四、完整程序四、完整程序 #include "stdio.h"#include "stdio.h" #include "string.h"#include "string.h" typedef char ElemType;typedef char ElemType; #define OK 1#define OK 1 /*/* 操作成功返回操作成功返回 1*/1*/ #define ERROR 0#define ERROR 0 /*/* 错误为错误为 0*/0*/ #define OVER -1#define OVER -1 /*/* 结束为结束为 -1*/-1*/ typedef struct node typedef struct node { int number;{ int number; /*/* 学生学号学生学号 */*/ char name[20];char name[20]; /*/* 学生姓名学生姓名 */*/ int chinese,math,english; /*int chinese,math,english; /* 学生语文、数学和英语成绩学生语文、数学和英语成绩 */*/ struct node *next;struct node *next; /*/* 指向下一结点的指针指向下一结点的指针 */*/ } LinkList;} LinkList; /* /* 定义学生结点类型定义学生结点类型
*/*/
/*********************/********************* 初始化链表初始化链表 **********************/**********************/
LinkList *InitList()LinkList *InitList()
{ LinkList *H;{ LinkList *H;
/*/* 申请一块申请一块 LinkListLinkList 类型的存储单元的操作,并将其地址类型的存储单元的操作,并将其地址赋值给头指针变量赋值给头指针变量 H*/H*/
H=(LinkList *)malloc(sizeof(LinkList)) ;H=(LinkList *)malloc(sizeof(LinkList)) ;
H->next=NULL;H->next=NULL;
return(H);return(H); /*/* 头结点头结点 HH 指针域为空,表示空链表指针域为空,表示空链表*/*/
}}
/******************/****************** 求链表长度求链表长度 *************************/*************************/
int Length_List(LinkList *H)int Length_List(LinkList *H)
{ LinkList *p;{ LinkList *p;
int j=0;int j=0;
p=H;p=H; /*p/*p 指向链表的头结点指向链表的头结点 */*/
while(p->next!=NULL)while(p->next!=NULL) /*/* 判断判断 pp 所指结点后面是否为空所指结点后面是否为空 */*/
{ p=p->next; { p=p->next; /*p/*p 向所指结点的后面移动向所指结点的后面移动 */*/
j++;j++; /*/* 计数器值增计数器值增 1*/1*/
}}
return j;return j; /*/* 计数器计数器 jj 的值为表长度的值为表长度 */*/
}}
/*****************/***************** 建立链表函数建立链表函数 ************************/************************/
void CreateList(LinkList *H,int n)void CreateList(LinkList *H,int n)
{ int i;{ int i;
LinkList *s,*last;LinkList *s,*last;
char ch;char ch;
last=H;last=H; /*last/*last 始终指向尾结点,开始时指向头结点始终指向尾结点,开始时指向头结点 */*/
for(i=1;i<=n;i++)for(i=1;i<=n;i++) /*/* 循环输入各学生成绩循环输入各学生成绩 */*/
{ s=(LinkList *) malloc(sizeof(LinkList)); /*{ s=(LinkList *) malloc(sizeof(LinkList)); /* 生成新结点生成新结点 */*/
printf("\nprintf("\n 请输入第请输入第 %d%d 个学生的学号:个学生的学号: ",i);",i);
scanf("%d",&s->number);scanf("%d",&s->number);
printf("\nprintf("\n 请输入第请输入第 %d%d 个学生的姓名:个学生的姓名: ",i);",i);
scanf("%s",s->name);scanf("%s",s->name);
printf("\nprintf("\n 请输入第请输入第 %d%d 个学生的语文、数学和英语成绩:个学生的语文、数学和英语成绩: ",i);",i);
scanf("%d%d%d",&s->chinese,&s->math,&s->english);scanf("%d%d%d",&s->chinese,&s->math,&s->english);
s->next=NULL;s->next=NULL; /*/* 将新结点的指针域为空将新结点的指针域为空 */*/
last->next=s;last->next=s; /*/* 将新结点插入表尾将新结点插入表尾 **//
last=s;last=s; /*/* 将将 lastlast 指针指向表尾指针指向表尾 **//
}}
}}
/*********************/********************* 表中元素定位函数表中元素定位函数 *******************/*******************/
LinkList *Locate(LinkList *H,int num)LinkList *Locate(LinkList *H,int num)
{ LinkList *p;{ LinkList *p;
p=H->next; /*pp=H->next; /*p 指向链表的第一个结点指向链表的第一个结点 */*/
while(p!=NULL && p->number!=num)while(p!=NULL && p->number!=num)
p=p->next;p=p->next;
return p;return p;
}}
/******************/****************** 查找表中元素位置函数查找表中元素位置函数 *******************/*******************/
LinkList *GetList(LinkList *H,int i)LinkList *GetList(LinkList *H,int i)
{ LinkList *p;{ LinkList *p;
int j=0;int j=0;
p=H;p=H; /*p/*p 指向链表的头结点指向链表的头结点 */*/
while(p->next!=NULL && j<i)while(p->next!=NULL && j<i)
{ p=p->next;{ p=p->next;
j++;j++;
}}
if(j==i)if(j==i) /*/* 判断与给定的序号是否相等判断与给定的序号是否相等 */*/
return p;return p;
elseelse
return NULL;return NULL;
}}
/******************/****************** 在链表中插入新元素函数在链表中插入新元素函数 ******************/******************/
int InsList(LinkList *p,LinkList x)int InsList(LinkList *p,LinkList x)
{ LinkList *s;{ LinkList *s;
s=(LinkList *)malloc(sizeof(LinkList));s=(LinkList *)malloc(sizeof(LinkList));
s->number=x.number;s->number=x.number;
strcpy(s->name,x.name);strcpy(s->name,x.name);
s->chinese=x.chinese;s->chinese=x.chinese;
s->math=x.math;s->math=x.math;
s->english=x.english;s->english=x.english; /*/* 将数据放入新结点的数据域将数据放入新结点的数据域 */*/
s->next=p->next;s->next=p->next; /*/* 将新结点的指针域与将新结点的指针域与 pp 结点后面元素相连结点后面元素相连*/*/
p->next=s;p->next=s; /*/* 将新结点插入链表将新结点插入链表 */*/
return OK; return OK;
}}
/****************/**************** 在给定位置在给定位置 ii 插入元素函数插入元素函数 *****************/*****************/
int Ins_List(LinkList *H, int i, LinkList x)int Ins_List(LinkList *H, int i, LinkList x)
{ LinkList *p;{ LinkList *p;
p=GetList(H, i-1);p=GetList(H, i-1); /*/* 调用按序号查找第调用按序号查找第 ii 个元素地址个元素地址 pp 函函数数 */*/
if(p!=NULL)if(p!=NULL) /*/* 判断查找的元素地址判断查找的元素地址 pp 是否存在是否存在 */*/
{ InsList(p,x);{ InsList(p,x); /*/* 调用在已知结点调用在已知结点 pp 后插入结点算法函数后插入结点算法函数 */*/
return OK;return OK;
}}
elseelse
return ERROR;return ERROR;
}}
/*******************/******************* 删除链表中的某元素函数删除链表中的某元素函数 ***********/***********/
int DelList(LinkList *p,LinkList *x)int DelList(LinkList *p,LinkList *x)
{ LinkList *s;{ LinkList *s;
s=p->next;s=p->next; /*s/*s 为要删除结点为要删除结点 */*/
x->number=s->number;x->number=s->number;
strcpy(x->name,s->name);strcpy(x->name,s->name);
x->chinese=s->chinese;x->chinese=s->chinese;
x->math=s->math;x->math=s->math;
x->english=s->english;x->english=s->english; /*/* 将要删除的数据赋予指针变量将要删除的数据赋予指针变量 X */X */
p->next=s->next;/*p->next=s->next;/* 将将 pp 结点的指针域与结点的指针域与 ss 结点后面元素相连结点后面元素相连 */*/
free(s); free(s); /*/* 释放结点释放结点 s*/s*/
return OK;return OK;
}}
/*****************/***************** 删除链表中给定位置的元素函数删除链表中给定位置的元素函数 ***************/***************/
int Del_List(LinkList *H,int i,LinkList *x)int Del_List(LinkList *H,int i,LinkList *x)
{ LinkList *p;{ LinkList *p;
p=GetList(H, i-1); /*p=GetList(H, i-1); /* 调用按序号查找第调用按序号查找第 i-1i-1 个元素地址个元素地址 pp 函函数数 */*/
if (p!=NULL && p->next!=NULL) /*if (p!=NULL && p->next!=NULL) /* 判断查找的元素地址判断查找的元素地址 pp 是否存是否存在在 */*/
{ DelList(p,x); /*{ DelList(p,x); /* 调用删除已知结点调用删除已知结点 pp 之后结点函数之后结点函数 */*/
return OK;return OK;
}}
elseelse
return ERROR;return ERROR;
}}
/**********************/********************** 主函数中的菜单显示主函数中的菜单显示 ********************/********************/
out()out()
{ printf("\n******************************************");{ printf("\n******************************************");
printf("\nprintf("\n 请输入序号(请输入序号( 0-40-4 )选择要进行的操作)选择要进行的操作 :");:");
printf("\n0------printf("\n0------ 退出退出 ");");
printf("\n1------printf("\n1------ 建立一个学生信息表建立一个学生信息表 ");");
printf("\n2------printf("\n2------ 插入一个学生信息插入一个学生信息 ");");
printf("\n3------printf("\n3------ 删除一个学生信息删除一个学生信息 ");");
printf("\n4------printf("\n4------ 查找一个学生是否在该学生信息表中查找一个学生是否在该学生信息表中 ");");
printf("\n******************************************\n");printf("\n******************************************\n");
}}
/**********************/********************** 输出表中信息函数输出表中信息函数 ********************/********************/
void DisLinkList(LinkList *H)void DisLinkList(LinkList *H)
{ LinkList *p;{ LinkList *p;
printf("\nprintf("\n 所有学生的信息如下所有学生的信息如下 :");:");
printf("\n printf("\n 学号学号 姓名姓名 语文语文 数学数学 英语英语 \n");\n");
p=H->next;p=H->next;
while(p!=NULL)while(p!=NULL)
{ printf("%2d%10s%9d%9d%9d\n",p->number,p->name,p-{ printf("%2d%10s%9d%9d%9d\n",p->number,p->name,p->chinese,>chinese,
p->math,p->english);p->math,p->english);
p=p->next;p=p->next;
}}
}}
/******************/****************** 主函数主函数 ****************************/****************************/
main()main()
{ LinkList *H,*p,*q,x;{ LinkList *H,*p,*q,x;
int i,n,menux,flag,num;int i,n,menux,flag,num;
clrscr(); /*clrscr(); /* 清屏清屏 */*/
out();out();
H=InitList();H=InitList();
scanf("%d",&menux);scanf("%d",&menux);
dodo
{ switch(menux){ switch(menux) /*/* 用来判断用来判断用户要进行何种操作用户要进行何种操作 */*/
{ case 0:exit(0); break;{ case 0:exit(0); break; /*/* 退出退出 */*/
case 1:case 1: /*/* 建立一个学生信息表建立一个学生信息表 */*/
printf("\nprintf("\n 请输入要生成的学生信息表的元素个请输入要生成的学生信息表的元素个数数 :");:");
scanf("%d",&n);scanf("%d",&n);
CreateList(H,n);CreateList(H,n);
printf("\nprintf("\n 建立的学生信息表为建立的学生信息表为 :\n");:\n");
DisLinkList(H);DisLinkList(H);
break;break;
case 2:case 2: /*/* 在学生信息表中插入一个元素在学生信息表中插入一个元素 */*/
printf("\nprintf("\n 请输入要插入的学生位置请输入要插入的学生位置 ");");
scanf("%d",&i);scanf("%d",&i);
printf("\nprintf("\n 请输入要插入的学生信息请输入要插入的学生信息 :");:");
printf("\nprintf("\n 请输入学生的学号:请输入学生的学号: ");");
scanf("%d",&x.number);scanf("%d",&x.number);
printf("\nprintf("\n 请输入学生的姓名:请输入学生的姓名: ");");
scanf("%s",x.name);scanf("%s",x.name);
printf("\nprintf("\n 请输入学生的语文、数学和英语成绩:请输入学生的语文、数学和英语成绩: ");");
scanf("%d%d%d",&x.chinese,&x.math,&x.english);scanf("%d%d%d",&x.chinese,&x.math,&x.english);
flag=Ins_List(H,i,x);flag=Ins_List(H,i,x);
if(flag)if(flag)
{ printf("\n{ printf("\n 插入后的学生信息表为插入后的学生信息表为 : ");: ");
DisLinkList(H);DisLinkList(H);
}}
break;break;
case 3:case 3: /*/* 在学生信息表中删除一个元素在学生信息表中删除一个元素 */*/
printf("\nprintf("\n 请输入要删除的学生的位置请输入要删除的学生的位置 :");:");
scanf("%d",&i);scanf("%d",&i);
flag=Del_List(H,i,&x);flag=Del_List(H,i,&x);
if(flag)if(flag)
{ printf("\n{ printf("\n 删除第删除第 %d%d 个学生后个学生后 ,, 表中信息表中信息为为 :",i);:",i);
DisLinkList(H);DisLinkList(H);
}}
break;break;
case 4:case 4: /*/* 在学生信息表中查找某学号学生信息在学生信息表中查找某学号学生信息 */*/
printf("\nprintf("\n 请输入查找的学生学号请输入查找的学生学号 :\n");:\n");
scanf("%d",&num);scanf("%d",&num);
if((q=Locate(H,num))!=NULL)if((q=Locate(H,num))!=NULL)
{ printf("\n{ printf("\n 在学生信息表中存在着学号为在学生信息表中存在着学号为 %d%d 的学的学生!生! ",num);",num);
printf("\nprintf("\n 学号学号 姓名姓名 语文语文 数学数学 英语英语 \n");\n");
printf("%2d%10s%9d%9d%9d",q->number,q->name,q-printf("%2d%10s%9d%9d%9d",q->number,q->name,q->chinese,>chinese,
q->math,q->english);q->math,q->english);
}}
elseelse
printf("\nprintf("\n 在学生信息表中不存在着学号为在学生信息表中不存在着学号为 %d%d 的的学生!学生! ",num);",num);
break;break;
default:default:
printf("\nprintf("\n 输入选项错误输入选项错误 ,, 请重新输入请重新输入 (0-4)!");(0-4)!");
}}
out();out();
scanf("%d",&menux);scanf("%d",&menux);
}while(1);}while(1);
}}
五、程序运行步骤及结果五、程序运行步骤及结果说明:程序运行自动显示的信息无下画说明:程序运行自动显示的信息无下画
线,用户输入的信息用下画线显示,线,用户输入的信息用下画线显示,“↙”表示回车。本程序有主菜单,“↙”表示回车。本程序有主菜单,设有设有 00 ~~ 44 五个选项,每次可以输入五个选项,每次可以输入00 ~~ 44 来执行相关操作,并且每次执行来执行相关操作,并且每次执行完后都会重新显示菜单,当输入0时完后都会重新显示菜单,当输入0时结束该程序。结束该程序。
程序一次运行结果如下:程序一次运行结果如下:
**************************************************************************************** 请输入序号(请输入序号( 0-40-4 )选择要进行的操作)选择要进行的操作 :: 0------0------ 退出退出 1------1------ 建立一个学生信息表建立一个学生信息表 2------2------ 插入一个学生信息插入一个学生信息 3------3------ 删除一个学生信息删除一个学生信息 4------4------ 查找一个是否在该学生信息表中查找一个是否在该学生信息表中 **************************************************************************************** 11↙↙
请输入要生成的学生信息表的元素个数请输入要生成的学生信息表的元素个数 ::22↙↙
请输入第请输入第 11 个学生的学号:个学生的学号: 11↙↙
请输入第请输入第 11 个学生的姓名:个学生的姓名: liuliu↙↙
请输入第请输入第 11 个学生的语文、数学和英语成绩:个学生的语文、数学和英语成绩: 78 88 8978 88 89↙↙
请输入第请输入第 22 个学生的学号:个学生的学号: 22↙↙
请输入第请输入第 22 个学生的姓名:个学生的姓名: wangwang↙↙
请输入第请输入第 22 个学生的语文、数学和英语成绩:个学生的语文、数学和英语成绩: 65 89 9365 89 93↙↙
建立的学生信息表为建立的学生信息表为 ::
学号学号 姓名姓名 语文语文 数学数学 英语英语1 liu 78 88 891 liu 78 88 89
2 wang 65 89 932 wang 65 89 93
****************************************************************************************
请输入序号(请输入序号( 0-40-4 )选择要进行的操作)选择要进行的操作 ::
0------0------ 退出退出1------1------ 建立一个学生信息表建立一个学生信息表2------2------ 插入一个学生信息插入一个学生信息3------3------ 删除一个学生信息删除一个学生信息4------4------ 查找一个是否在该学生信息表中查找一个是否在该学生信息表中****************************************************************************************
22↙↙
请输入要插入的学生位置请输入要插入的学生位置 33↙↙
请输入要插入的学生信息请输入要插入的学生信息 ::
请输入学生的学号:请输入学生的学号: 33↙↙
请输入学生的姓名:请输入学生的姓名: zhaozhao↙↙
请输入学生的语文、数学和英语成绩:请输入学生的语文、数学和英语成绩: 92 75 8192 75 81↙↙
插入后的学生信息表为插入后的学生信息表为 ::
学号学号 姓名姓名 语文语文 数学数学 英语英语1 liu 78 88 891 liu 78 88 89
2 wang 65 89 932 wang 65 89 93
3 zhao 92 75 813 zhao 92 75 81
****************************************************************************************
请输入序号(请输入序号( 0-40-4 )选择要进行的操作)选择要进行的操作 ::
0------0------ 退出退出1------1------ 建立一个学生信息表建立一个学生信息表2------2------ 插入一个学生信息插入一个学生信息3------3------ 删除一个学生信息删除一个学生信息4------4------ 查找一个是否在该学生信息表中查找一个是否在该学生信息表中****************************************************************************************
33↙↙
请输入要删除的学生的位置请输入要删除的学生的位置 ::22↙↙
删除第删除第 22 个学生后个学生后 ,, 表中信息为表中信息为 ::
学号学号 姓名姓名 语文语文 数学数学 英语英语1 liu 78 88 891 liu 78 88 89
3 zhao 92 75 813 zhao 92 75 81
****************************************************************************************
请输入序号(请输入序号( 0-40-4 )选择要进行的操作)选择要进行的操作 ::
0------0------ 退出退出1------1------ 建立一个学生信息表建立一个学生信息表2------2------ 插入一个学生信息插入一个学生信息3------3------ 删除一个学生信息删除一个学生信息4------4------ 查找一个是否在该学生信息表中查找一个是否在该学生信息表中****************************************************************************************
44
请输入查找的学生学号请输入查找的学生学号 ::33↙↙
学号学号 姓名姓名 语文语文 数学数学 英语英语3 zhao 92 75 813 zhao 92 75 81
****************************************************************************************
请输入序号(请输入序号( 0-40-4 )选择要进行的操作)选择要进行的操作 ::
0------0------ 退出退出1------1------ 建立一个学生信息表建立一个学生信息表2------2------ 插入一个学生信息插入一个学生信息3------3------ 删除一个学生信息删除一个学生信息4------4------ 查找一个是否在该学生信息表中查找一个是否在该学生信息表中****************************************************************************************
00↙↙