目录
目录README.md

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");
    }
}

}

邀请码
    Gitlink(确实开源)
  • 加入我们
  • 官网邮箱:gitlink@ccf.org.cn
  • QQ群
  • QQ群
  • 公众号
  • 公众号

©Copyright 2023 CCF 开源发展委员会
Powered by Trustie& IntelliDE 京ICP备13000930号