C语言--学生成绩管理系统--附源代码(结构体,链表,结构体指针)
作者:互联网
一、实训目的
通过本实训,主要目的是让学生掌握以下知识点:
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 <stdio.h>
#include <stdlib.h>
#include <string.h>
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 %3d\n",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 %3d\n",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上许多优秀创作者的代码与思路,非常感谢这些乐于开源的创作者们!
标签:pr,four,--,next,链表,linklist,score,学生,源代码 来源: https://blog.csdn.net/m0_62351105/article/details/123613966