main
include <stdio.h>
include <stdlib.h>
include <string.h>
define NAME_LEN 50 // 姓名最大长度
define SUBJECT_NUM 3 // 科目数量(示例:语文、数学、英语)
define SCORE_RANGE 100 // 单科成绩范围(0~100)
// 学生信息结构体
typedef struct Student {
int id; // 学号
char name[NAME_LEN]; // 姓名
int scores[SUBJECT_NUM]; // 各科成绩(索引0:语文, 1:数学, 2:英语)
int total; // 总分
float avg; // 平均分
} Student;
// 链表节点结构体
typedef struct Node {
Student stu; // 学生信息
struct Node *next; // 指向下一节点的指针
} Node, *StudentList; // StudentList为指向Node的指针类型
// ===================== 工具函数 =====================
// 计算总分和平均分
void calculateScore(Student *stu) {
stu->total = stu->scores[0] + stu->scores[1] + stu->scores[2];
stu->avg = stu->total * 1.0 / SUBJECT_NUM;
}
// 检查学号是否已存在(防止重复)
int isIDExists(StudentList head, int targetID) {
Node *p = head;
while (p != NULL) {
if (p->stu.id == targetID) {
return 1; // 存在
}
p = p->next;
}
return 0; // 不存在
}
// ===================== 核心功能函数 =====================
// 初始化空链表
StudentList initList() {
return NULL;
}
// 添加学生(尾插法,保证顺序;自动检查学号唯一性)
void addStudent(StudentList *head) {
Node *newNode = (Node *)malloc(sizeof(Node));
if (newNode == NULL) {
printf(“内存分配失败!\n”);
return;
}
// 输入学号(检查唯一性)
int id;
while (1) {
printf("请输入学号:");
scanf("%d", &id);
if (isIDExists(*head, id)) {
printf("学号%d已存在,请重新输入!\n", id);
} else {
newNode->stu.id = id;
break;
}
}
// 输入姓名
printf("请输入姓名:");
scanf("%s", newNode->stu.name);
// 输入各科成绩(验证范围:0~100)
for (int i = 0; i < SUBJECT_NUM; i++) {
int score;
while (1) {
printf("请输入第%d科成绩(0~100):", i + 1);
scanf("%d", &score);
if (score < 0 || score > SCORE_RANGE) {
printf("成绩超出范围(0~100),请重新输入!\n");
} else {
newNode->stu.scores[i] = score;
break;
}
}
}
// 计算总分和平均分
calculateScore(&newNode->stu);
newNode->next = NULL;
// 插入链表尾部
if (*head == NULL) {
*head = newNode;
} else {
Node *p = *head;
while (p->next != NULL) {
p = p->next;
}
p->next = newNode;
}
printf("学生信息添加成功!\n");
}
// 显示所有学生信息
void showAllStudents(StudentList head) {
if (head == NULL) {
printf(“当前无学生信息!\n”);
return;
}
printf(“\n===== 所有学生信息 =====\n”);
printf(“学号\t姓名\t语文\t数学\t英语\t总分\t平均分\n”);
Node *p = head;
while (p != NULL) {
printf(“%d\t%s\t%d\t%d\t%d\t%d\t%.2f\n”,
p->stu.id,
p->stu.name,
p->stu.scores[0],
p->stu.scores[1],
p->stu.scores[2],
p->stu.total,
p->stu.avg);
p = p->next;
}
}
// 按学号查询学生
void searchByID(StudentList head, int targetID) {
Node *p = head;
while (p != NULL) {
if (p->stu.id == targetID) {
printf(“\n找到学号为%d的学生:\n”, targetID);
printf(“学号\t姓名\t语文\t数学\t英语\t总分\t平均分\n”);
printf(“%d\t%s\t%d\t%d\t%d\t%d\t%.2f\n”,
p->stu.id,
p->stu.name,
p->stu.scores[0],
p->stu.scores[1],
p->stu.scores[2],
p->stu.total,
p->stu.avg);
return;
}
p = p->next;
}
printf(“未找到学号为%d的学生!\n”, targetID);
}
// 按姓名查询学生(支持重名)
void searchByName(StudentList head, char *targetName) {
Node *p = head;
int found = 0;
while (p != NULL) {
if (strcmp(p->stu.name, targetName) == 0) {
if (!found) {
printf(“\n找到姓名为%s的学生:\n”, targetName);
printf(“学号\t姓名\t语文\t数学\t英语\t总分\t平均分\n”);
found = 1;
}
printf(“%d\t%s\t%d\t%d\t%d\t%d\t%.2f\n”,
p->stu.id,
p->stu.name,
p->stu.scores[0],
p->stu.scores[1],
p->stu.scores[2],
p->stu.total,
p->stu.avg);
}
p = p->next;
}
if (!found) {
printf(“未找到姓名为%s的学生!\n”, targetName);
}
}
// 按学号删除学生
void deleteStudent(StudentList *head, int targetID) {
Node *p = *head, *pre = NULL;
while (p != NULL && p->stu.id != targetID) {
pre = p;
p = p->next;
}
if (p == NULL) {
printf(“未找到学号为%d的学生,删除失败!\n”, targetID);
return;
}
// 调整链表指针
if (pre == NULL) { // 头节点是目标节点
*head = p->next;
} else {
pre->next = p->next;
}
free(p); // 释放内存
printf(“学号为%d的学生信息已删除!\n”, targetID);
}
// 按总分降序排序(冒泡排序,交换节点数据)
void sortByTotal(StudentList *head) {
if (*head == NULL || (*head)->next == NULL) {
printf(“无学生信息或仅1条,无需排序!\n”);
return;
}
Node *p, *q, *tail = NULL;
int swapped;
do {
swapped = 0;
p = *head;
while (p->next != tail) {
q = p->next;
// 降序:若前节点总分 < 后节点总分,则交换数据
if (p->stu.total < q->stu.total) {
Student temp = p->stu;
p->stu = q->stu;
q->stu = temp;
swapped = 1;
}
p = p->next;
}
tail = p; // 最后一个节点已排好序
} while (swapped);
printf(“已按总分降序排序!\n”);
}
// ===================== 主函数(菜单交互) =====================
int main() {
StudentList head = initList(); // 初始化空链表
int choice, id;
char name[NAME_LEN];
printf(“小组成员:徐睿泽,何宇初,杨浩,毕浩然,陈遨怀,敖雪成,徐凌飞\n”);
while (1) {
printf(“\n===== 学生成绩管理系统 =====\n”);
printf(“1. 添加学生信息\n”);
printf(“2. 显示所有学生信息\n”);
printf(“3. 按学号查询\n”);
printf(“4. 按姓名查询\n”);
printf(“5. 删除学生信息(按学号)\n”);
printf(“6. 按总分降序排序\n”);
printf(“0. 退出系统\n”);
printf(“请输入操作编号:”);
scanf(“%d”, &choice);
switch (choice) {
case 1: {
addStudent(&head);
break;
}
case 2: {
showAllStudents(head);
break;
}
case 3: {
printf("请输入要查询的学号:");
scanf("%d", &id);
searchByID(head, id);
break;
}
case 4: {
printf("请输入要查询的姓名:");
scanf("%s", name);
searchByName(head, name);
break;
}
case 5: {
printf("请输入要删除的学号:");
scanf("%d", &id);
deleteStudent(&head, id);
break;
}
case 6: {
sortByTotal(&head);
break;
}
case 0:{
printf("感谢使用,退出系统!\n");
// 释放链表内存(防止内存泄漏)
Node *p = head, *q;
while (p != NULL) {
q = p->next;
free(p);
p = q;
}
return 0;
}
default:
printf("无效操作,请重新输入!\n");
}
}
}
main
include <stdio.h>
include <stdlib.h>
include <string.h>
define NAME_LEN 50 // 姓名最大长度
define SUBJECT_NUM 3 // 科目数量(示例:语文、数学、英语)
define SCORE_RANGE 100 // 单科成绩范围(0~100)
// 学生信息结构体 typedef struct Student { int id; // 学号 char name[NAME_LEN]; // 姓名 int scores[SUBJECT_NUM]; // 各科成绩(索引0:语文, 1:数学, 2:英语) int total; // 总分 float avg; // 平均分 } Student;
// 链表节点结构体 typedef struct Node { Student stu; // 学生信息 struct Node *next; // 指向下一节点的指针 } Node, *StudentList; // StudentList为指向Node的指针类型
// ===================== 工具函数 ===================== // 计算总分和平均分 void calculateScore(Student *stu) { stu->total = stu->scores[0] + stu->scores[1] + stu->scores[2]; stu->avg = stu->total * 1.0 / SUBJECT_NUM; }
// 检查学号是否已存在(防止重复) int isIDExists(StudentList head, int targetID) { Node *p = head; while (p != NULL) { if (p->stu.id == targetID) { return 1; // 存在 } p = p->next; } return 0; // 不存在 }
// ===================== 核心功能函数 ===================== // 初始化空链表 StudentList initList() { return NULL; }
// 添加学生(尾插法,保证顺序;自动检查学号唯一性) void addStudent(StudentList *head) { Node *newNode = (Node *)malloc(sizeof(Node)); if (newNode == NULL) { printf(“内存分配失败!\n”); return; }
}
// 显示所有学生信息 void showAllStudents(StudentList head) { if (head == NULL) { printf(“当前无学生信息!\n”); return; } printf(“\n===== 所有学生信息 =====\n”); printf(“学号\t姓名\t语文\t数学\t英语\t总分\t平均分\n”); Node *p = head; while (p != NULL) { printf(“%d\t%s\t%d\t%d\t%d\t%d\t%.2f\n”, p->stu.id, p->stu.name, p->stu.scores[0], p->stu.scores[1], p->stu.scores[2], p->stu.total, p->stu.avg); p = p->next; } }
// 按学号查询学生 void searchByID(StudentList head, int targetID) { Node *p = head; while (p != NULL) { if (p->stu.id == targetID) { printf(“\n找到学号为%d的学生:\n”, targetID); printf(“学号\t姓名\t语文\t数学\t英语\t总分\t平均分\n”); printf(“%d\t%s\t%d\t%d\t%d\t%d\t%.2f\n”, p->stu.id, p->stu.name, p->stu.scores[0], p->stu.scores[1], p->stu.scores[2], p->stu.total, p->stu.avg); return; } p = p->next; } printf(“未找到学号为%d的学生!\n”, targetID); }
// 按姓名查询学生(支持重名) void searchByName(StudentList head, char *targetName) { Node *p = head; int found = 0; while (p != NULL) { if (strcmp(p->stu.name, targetName) == 0) { if (!found) { printf(“\n找到姓名为%s的学生:\n”, targetName); printf(“学号\t姓名\t语文\t数学\t英语\t总分\t平均分\n”); found = 1; } printf(“%d\t%s\t%d\t%d\t%d\t%d\t%.2f\n”, p->stu.id, p->stu.name, p->stu.scores[0], p->stu.scores[1], p->stu.scores[2], p->stu.total, p->stu.avg); } p = p->next; } if (!found) { printf(“未找到姓名为%s的学生!\n”, targetName); } }
// 按学号删除学生 void deleteStudent(StudentList *head, int targetID) { Node *p = *head, *pre = NULL; while (p != NULL && p->stu.id != targetID) { pre = p; p = p->next; } if (p == NULL) { printf(“未找到学号为%d的学生,删除失败!\n”, targetID); return; } // 调整链表指针 if (pre == NULL) { // 头节点是目标节点 *head = p->next; } else { pre->next = p->next; } free(p); // 释放内存 printf(“学号为%d的学生信息已删除!\n”, targetID); }
// 按总分降序排序(冒泡排序,交换节点数据) void sortByTotal(StudentList *head) { if (*head == NULL || (*head)->next == NULL) { printf(“无学生信息或仅1条,无需排序!\n”); return; } Node *p, *q, *tail = NULL; int swapped; do { swapped = 0; p = *head; while (p->next != tail) { q = p->next; // 降序:若前节点总分 < 后节点总分,则交换数据 if (p->stu.total < q->stu.total) { Student temp = p->stu; p->stu = q->stu; q->stu = temp; swapped = 1; } p = p->next; } tail = p; // 最后一个节点已排好序 } while (swapped); printf(“已按总分降序排序!\n”); }
// ===================== 主函数(菜单交互) ===================== int main() { StudentList head = initList(); // 初始化空链表 int choice, id; char name[NAME_LEN]; printf(“小组成员:徐睿泽,何宇初,杨浩,毕浩然,陈遨怀,敖雪成,徐凌飞\n”); while (1) { printf(“\n===== 学生成绩管理系统 =====\n”); printf(“1. 添加学生信息\n”); printf(“2. 显示所有学生信息\n”); printf(“3. 按学号查询\n”); printf(“4. 按姓名查询\n”); printf(“5. 删除学生信息(按学号)\n”); printf(“6. 按总分降序排序\n”); printf(“0. 退出系统\n”); printf(“请输入操作编号:”); scanf(“%d”, &choice);
}