文章目录
- 1-5题
- 题目
- 例题8(难度★ ★ ★ ★ ☆)
- 答案
- 例题8
- 答案1
- 解析
- 答案2
- 解析
1-5题
C语言基础例题1-3题-指针篇
C语言基础例题4-5题-二维数组篇
C语言基础例题6-7题-结构体篇
题目
例题8(难度★ ★ ★ ★ ☆)
编写一个学生成绩管理系统,实现以下功能:
- 添加学生信息:从键盘输入学生的姓名和成绩,将学生信息添加到系统中。
- 删除学生信息:从键盘输入要删除的学生姓名,若学生存在则将其从系统中删除。
- 查找学生信息:从键盘输入要查询的学生姓名,若学生存在则显示学生姓名和成绩,否则提示查无此人。
- 修改学生成绩:从键盘输入要修改成绩的学生姓名和新的成绩,若学生存在则将其成绩修改为新的成绩。
- 显示所有学生信息:显示系统中所有学生的姓名和成绩。
- 退出程序:结束学生成绩管理系统。
运行结果如下所示:
答案
例题8
答案1
#include <stdio.h>
#include <stdlib.h>
#include <string.h>// 定义学生信息结构体
typedef struct
{char name[20];int score;
} Student;// 定义链表节点结构体
typedef struct Node
{Student data;struct Node *next;
} Node;// 在链表末尾添加新节点(学生信息)
void addStudent(Node *head)
{Node *p = head;while (p->next != NULL){p = p->next;}Node *newNode = (Node *)malloc(sizeof(Node));printf("请输入学生姓名:");scanf("%s", newNode->data.name);printf("请输入成绩:");scanf("%d", &(newNode->data.score));newNode->next = NULL;p->next = newNode;printf("添加成功!\n");
}// 根据学生姓名删除节点
void deleteStudent(Node *head)
{char name[20];printf("请输入要删除的学生姓名:");scanf("%s", name);Node *p = head->next;Node *prev = head;while (p != NULL){if (strcmp(p->data.name, name) == 0){ // 学生姓名匹配,删除节点prev->next = p->next;free(p);printf("删除成功!\n");return;}prev = p;p = p->next;}printf("查无此人!\n");
}// 根据学生姓名查找学生信息
void findStudent(Node *head)
{char name[20];printf("请输入要查询的学生姓名:");scanf("%s", name);Node *p = head->next;while (p != NULL){if (strcmp(p->data.name, name) == 0){ // 学生姓名匹配,显示学生信息printf("姓名:%s\t成绩:%d\n", p->data.name, p->data.score);return;}p = p->next;}printf("查无此人!\n");
}// 根据学生姓名修改学生成绩
void modifyScore(Node *head)
{char name[20];int newScore;printf("请输入要修改成绩的学生姓名:");scanf("%s", name);printf("请输入新的成绩:");scanf("%d", &newScore);Node *p = head->next;while (p != NULL){if (strcmp(p->data.name, name) == 0){ // 学生姓名匹配,修改成绩p->data.score = newScore;printf("修改成功!\n");return;}p = p->next;}printf("查无此人!\n");
}// 显示所有学生信息
void displayStudents(Node *head)
{Node *p = head->next;while (p != NULL){printf("姓名:%s\t成绩:%d\n", p->data.name, p->data.score);p = p->next;}
}int main()
{Node *head = (Node *)malloc(sizeof(Node));head->next = NULL;int option;do{printf("【菜单】\n");printf("1. 添加学生信息\n");printf("2. 删除学生信息\n");printf("3. 查找学生信息\n");printf("4. 修改学生成绩\n");printf("5. 显示所有学生信息\n");printf("6. 退出程序\n");printf("\n请选择菜单选项:");scanf("%d", &option);switch (option){case 1:addStudent(head);break;case 2:deleteStudent(head);break;case 3:findStudent(head);break;case 4:modifyScore(head);break;case 5:displayStudents(head);break;case 6:printf("程序结束!\n");break;default:printf("错误!没有此选项!\n");break;}} while (option != 6);// 释放链表内存Node *p = head;while (p != NULL){Node *temp = p->next;free(p);p = temp;}return 0;
}
解析
struct _StudentItem:定义了学生信息的结构体。它包含一个char数组name用于存储学生姓名,一个int变量score用于存储成绩。
struct Node:定义了链表节点的结构体。它包含了一个Student类型的数据成员data用于存储学生信息,以及一个指向下一个节点的指针next。
addStudent:在链表末尾添加新节点(学生信息)。该函数首先遍历链表,找到最后一个节点,然后创建一个新节点,要求用户输入学生的姓名和成绩,并将新节点添加到链表末尾。
deleteStudent:根据学生姓名删除节点。该函数要求用户输入要删除的学生姓名,然后从链表头开始遍历每个节点,寻找匹配的学生姓名。如果找到匹配的节点,则删除该节点,并释放内存。如果没有找到匹配的节点,输出"查无此人!"。
findStudent:根据学生姓名查找学生信息。该函数要求用户输入要查询的学生姓名,然后从链表头开始遍历每个节点,寻找匹配的学生姓名。如果找到匹配的节点,则输出该学生的姓名和成绩。如果没有找到匹配的节点,输出"查无此人!"。
modifyScore:根据学生姓名修改学生成绩。该函数要求用户输入要修改成绩的学生姓名和新的成绩,然后从链表头开始遍历每个节点,寻找匹配的学生姓名。如果找到匹配的节点,则修改该节点的成绩为新的成绩。如果没有找到匹配的节点,输出"查无此人!"。
displayStudents:显示所有学生信息。该函数从链表头开始遍历每个节点,并输出每个节点的学生姓名和成绩。
在主函数里,我们首先创建了一个链表头指针head,然后使用一个菜单循环,等待用户输入菜单选项。根据用户的选择,调用相应的函数执行相应的功能。直到用户选择退出程序为止。最后,释放了链表的内存。
答案2
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义学生信息结构体
typedef struct _StudentItem
{char name[9];float grade;
} StudentItem;
// 定义链表节点结构体
typedef struct _StudentNode
{StudentItem item;struct _StudentNode *next;
} StudentNode;
// 在链表开头添加新节点(学生信息)
void AddStudent(StudentNode **student);
// 根据学生姓名删除节点
void DeleteStudent(StudentNode **student, char *name);
// 根据学生姓名修改学生成绩
void ModifyGrades(StudentNode *student, float grade);
// 显示所有学生信息
void displayStudents(StudentNode **student);
// 根据学生姓名查找学生信息
StudentNode *FindStudent(StudentNode **student, char *name);
// 释放链表内存
void FreeNode(StudentNode **student);int main(void)
{StudentNode *student = NULL, *target;int selection;char name[9];float grade;printf("【菜单】\n1.添加学生信息\n2.删除学生信息\n3.查找学生信息\n4.修改学生成绩\n5.显示所有学生信息\n6.退出程序\n");while (scanf("%d", &selection) == 1 && selection != 6){switch (selection){case 1:AddStudent(&student);break;case 2:printf("请输入要删除的学生名:");scanf("%s", name);DeleteStudent(&student, name);break;case 3:printf("请输入要查询的学生名:");scanf("%s", name);target = FindStudent(&student, name);if (target == NULL)printf("查无此人!\n");elseprintf("姓名:%s\t成绩:%f\n", target->item.name, target->item.grade);break;case 4:printf("请输入要修改成绩的学生名:");scanf("%s", name);target = FindStudent(&student, name);if (target == NULL)printf("查无此人!\n");else{printf("请输入新的成绩:");scanf("%f", &grade);ModifyGrades(target, grade);puts("修改成功");}break;case 5:displayStudents(&student);break;default:printf("错误!没有此选项!\n");break;}printf("继续输入选项:\n");}FreeNode(&student);getchar();getchar();return 0;
}
void AddStudent(StudentNode **student)
{StudentNode *temp = (StudentNode *)malloc(sizeof(StudentNode));printf("请输入学生姓名:");scanf("%s", temp->item.name);printf("请输入成绩:");scanf("%f", &temp->item.grade);temp->next = *student;*student = temp;
}
void DeleteStudent(StudentNode **student, char *name)
{StudentNode *target = *student, *prev;// 学生姓名匹配,删除节点if (target != NULL && !strcmp(target->item.name, name)){*student = target->next;}else{prev = target;target = target->next;while (target != NULL){// 学生姓名匹配,删除节点if (!strcmp(target->item.name, name)){prev->next = target->next;break;}prev = target;target = target->next;}}if (target != NULL){free(target);printf("删除成功!\n");}else{printf("删除失败!\n");}
}
void ModifyGrades(StudentNode *student, float grade)
{student->item.grade = grade;
}
StudentNode *FindStudent(StudentNode **student, char *name)
{StudentNode *p = *student;while (p != NULL){// 学生姓名匹配,返回学生节点if (!strcmp(p->item.name, name))break;p = p->next;}return p;
}
void displayStudents(StudentNode **student)
{const StudentNode *p = *student;if (*student == NULL){printf("没有学生数据\n");}else{while (p != NULL){printf("姓名:%s\t成绩%f\n", p->item.name, p->item.grade);p = p->next;}}
}
void FreeNode(StudentNode **student)
{StudentNode *target=*student,*next;while(target!=NULL){next=target->next;free(target);target=next;}
}
解析
我们使用链表来存储学生的信息,也就是姓名和成绩。根据题目要求需要实现添加学生、删除学生、查找学生、修改学生的成绩、显示所有学生的信息,退出的功能。
首先,我们定义了两个结构体:StudentItem 和 StudentNode。StudentItem 用来存储学生的姓名和成绩,而 StudentNode 用来表示链表中的节点,它包含一个 StudentItem 类型的变量和一个指向下一个节点的指针。
然后,我们实现一些函数来完成不同的操作。AddStudent 函数用于在链表开头添加一个新的学生节点;DeleteStudent 函数用于根据学生的姓名来删除对应的节点;ModifyGrades 函数根据学生的姓名来修改他们的成绩;displayStudents 函数显示所有学生的信息;FindStudent 函数根据学生的姓名来查找他们的信息;最后,FreeNode 函数用来释放链表的内存。
在主函数中,我们通过一个循环来让用户选择要执行的操作。根据用户的输入,我们会调用相应的函数来处理操作。比如,如果用户选择添加学生,我们会创建一个新的节点,然后获取学生的姓名和成绩,最后将其添加到链表的开头。
如果要删除学生,我们先根据学生的姓名找到对应的节点,然后将其从链表中删除并释放其内存。修改学生的成绩,先根据学生的姓名找到对应的节点,然后更改他的成绩。显示所有学生的信息,就遍历链表并打印每个学生的姓名和成绩。
在程序结束时,记得释放链表的内存。