一、实训目的
通过本实训,主要目的是让学生掌握以下知识点:
1、结构体数组的定义和使用。
2、结构体数据的输入与输出方法。
3、插入、排序、查找、删除算法的实现。
4、初步了解一个简单管理系统的设计方法。
二、实训内容
1、输入:函数input把10个学生的学号、姓名、性别、年龄、四科成绩以及平均成绩和总成绩放在一个结构体数组中,学生的学号、姓名、四科成绩由键盘输入,然后计算出平均成绩和总成绩放在结构体对应的域中。
2、插入:insert 函数输入一个学生的记录,按学号的先后顺序插入该学生的全部内容。
3、排序:sort函数对所有学生按要求排序(1.学号 2.总成绩 ),并输出。
4、查找:find函数输入一个学生的学号或姓名,找到该学生并输出该学生的全部内容。要求能查询多次。
5、删除:delete函数输入一个学生的学号或姓名,找到该学生并删除该学生的全部内容。
6、输出:函数output 输出全部学生的记录。
7、main调用所有函数,实现全部函数功能(注:除了定义结构外,不允许使用全局变量,函数之间的数据全部使用参数传递)。
三、实训过程
(图1 录入学生记录) (图2 输入学生记录)
进入程序后,函数input把10个学生的学号、姓名、性别、年龄、四科成绩以及平均成绩和总成绩放在一个结构体数组中,学生的学号、姓名、四科成绩由键盘输入,然后计算出平均成绩和总成绩放在结构体对应的域中。显示录入学生记录,录入完毕后显示录入结果(图1)。
之后显示学生成绩录入系统的主要功能,首先我选择了“1.输入学生记录”,就可以调用insert 函数,输入一个学生的记录,按学号的先后顺序插入该学生的全部内容,并显示插入后的结果(图2)。
(图3 选择学号排序) (图4 选择成绩排序)
接下来选择“2.排序学生记录”,将调用sort函数对所有学生按要求排序,可选择按照学号或者成绩顺序排序,按照学号排序后并显示排序结果(图3),按照成绩排序后并显示排序结果(图4)。
(图5 查找学生功能)
接下来选择“3.查找学生记录”,将调用find函数,输入一个学生的学号或姓名,将找到该学生并输出该学生的全部内容(图5)。
(图6 按名字删除学生记录) (图7 按学号删除学生记录)
选择“4.删除学生记录”,将调用delete函数,输入一个学生的学号或姓名,将找到该学生并从学生记录中删除(图6,7)。
(图8 退出系统)
运行完全部功能后,可以选择“6.退出系统”,即退出学生成绩管理系统(图8)。
以下是程序的源代码
#include#include #include typedef struct student{ //定义学生的结构体 int number; //学号 char name[50]; //姓名 char sex[3]; //性别 int age; //年龄 int four_score[4]; //四科成绩 int average_score; //平均成绩 int total_score; //总成绩 struct student *next; //指向下一结构体的指针 } LinkList; LinkList *input(); void output(LinkList *linklist); void insert(LinkList *linklist); void delete(LinkList *linklist); void find(LinkList *linklist); void sort(LinkList *linklist); int main() { char c; int j=1; printf("请输入学生的学号、姓名、性别、年龄与四科成绩:n"); LinkList *linklist = input(); //调用input函数 printf("n以下是录入的学生:n"); output(linklist); while(j) { printf("n1.输入学生记录n2.排序学生记录n3.查找学生记录n4.删除学生记录n5.输出学生记录n6.退出系统n"); printf("请选择你想要执行的操作:n"); scanf(" %c",&c); if(c =='1'){ //输入学生记录 insert(linklist); printf("以下是修改后的表格:n"); output(linklist); } else if(c == '2'){ //排序学生记录 sort(linklist); printf("以下是修改后的表格:n"); output(linklist); } else if(c =='3'){ //查找学生记录 find(linklist); } else if(c =='4'){ //删除学生记录 delete(linklist); printf("以下是修改后的表格:n"); output(linklist); } else if(c == '5'){ //输出学生记录 output(linklist); } else if(c == '6'){ //退出系统 printf("已退出"); j=0; } } getchar();getchar(); return 0; } LinkList *input(){ LinkList *head=NULL, *node=NULL, *end=NULL; //定义头节点,普通节点,尾部节点,并初始化 head = (LinkList*)malloc(sizeof(LinkList));//分配地址 end = head; //若是空链表则头尾节点一样 for (int i = 0; i <10; i++) { node = (LinkList*)malloc(sizeof(LinkList)); scanf("%d %s %s %d %d %d %d %d",&node->number,node->name,node->sex,&node->age,&node->four_score[0],&node->four_score[1],&node->four_score[2],&node->four_score[3]); node->average_score = (node->four_score[0]+node->four_score[1]+node->four_score[2]+node->four_score[3])/4; node->total_score = node->four_score[0]+node->four_score[1]+node->four_score[2]+node->four_score[3]; end->next = node; end = node; } end->next = NULL; //结束创建,给end的指针域置空 return head; //返回头节点的地址 } void output(LinkList *linklist) { int j=1; LinkList *p = linklist; while (p->next != NULL) { p = p->next; printf("%d. %d %s %s %d %-3d %-3d %-3d %-3d %-3d %3dn",j,p->number,p->name,p->sex,p->age,p->four_score[0],p->four_score[1],p->four_score[2],p->four_score[3],p->average_score,p->total_score); j++; } } void insert(LinkList *linklist) { LinkList *p = linklist,*pr; pr = (LinkList*)malloc(sizeof(LinkList)); //让pr指向新建节点申请的内存 printf("请输入学生记录的值:n"); scanf("%d %s %s %d %d %d %d %d",&pr->number,pr->name,pr->sex,&pr->age,&pr->four_score[0],&pr->four_score[1],&pr->four_score[2],&pr->four_score[3]); pr->average_score = (pr->four_score[0]+pr->four_score[1]+pr->four_score[2]+pr->four_score[3])/4; pr->total_score = pr->four_score[0]+pr->four_score[1]+pr->four_score[2]+pr->four_score[3]; while((p->next->number)<(pr->number)){ p = p->next; if(p->next==NULL){ break; } } if(p!=NULL){ pr->next = p->next; //将新建节点的地址指向将要插入节点的后一个节点的地址 p->next = pr; //使插入节点指向新建节点 } else{ pr->next = NULL; p->next = pr; } } void delete(LinkList *linklist) { char date[50]={0}; int num; LinkList *p = linklist,*pr = linklist; printf("删除哪位学生记录:n"); scanf("%s",date); 输入需删除的数据,姓名或学号 if (strspn(date, "0123456789") == strlen(date)){ num=atoi(date); while(num != (p->number)||(strcmp(date,p->name)==0)){ //或后面那句我不知道我写的啥意思,但是程序都运行成功了,我就不改了 pr = p; p = p->next; if(p==NULL){ break; } } } else{ while(strcmp(date,p->name)!=0){ pr = p; p = p->next; if(p==NULL){ break; } } } if(p!=NULL){ pr->next = p->next; free(p); } else{ pr->next = NULL; free(p); } } void find(LinkList *linklist) { char date[50]={0}; int num; LinkList *p = linklist; printf("查找哪位学生记录:n"); scanf("%s",date); //输入需查找的数据,姓名或学号 if (strspn(date, "0123456789") == strlen(date)){ //判断是否为学号(数字) num=atoi(date); //是的话转换为数字 while(num != (p->number)||(strcmp(date,p->name)==0)){ //或后面那句我不知道我写的啥意思,但是程序都运行成功了,我就不改了 p = p->next; if(p==NULL){ break; } } } else{ while(strcmp(date,p->name)!=0){ //判断名字是否相同 p = p->next; if(p==NULL){ break; } } } printf("%d %s %s %d %-3d %-3d %-3d %-3d %-3d %3dn",p->number,p->name,p->sex,p->age,p->four_score[0],p->four_score[1],p->four_score[2],p->four_score[3],p->average_score,p->total_score); } void sort(LinkList *linklist) //用了冒泡排序,可以在网上搜链表的冒泡排序 { char b; LinkList *pr,*p,*tail,*temp; tail = NULL; pr = linklist; printf("选择哪种排序方式(1.学号 2.总成绩):n"); scanf(" %c",&b); while ((linklist->next->next)!=tail){ p = linklist->next; pr = linklist; while (p->next!=tail){ if(b == '1'){ if((p->number)>(p->next->number)){ pr->next=p->next; temp=p->next->next; p->next->next=p; p->next=temp; p=pr->next; } } else if(b == '2'){ if((p->total_score)>(p->next->total_score)){ pr->next=p->next; temp=p->next->next; p->next->next=p; p->next=temp; p=pr->next; } } p=p->next; pr=pr->next; } tail=p; } }
四、实训总结
实训的成果,代码写的一般,欢迎大家指点,其中有许多不会的地方,参考了csdn上许多优秀创作者的代码与思路,非常感谢这些乐于开源的创作者们!



