C语言学生成绩管理系统设计思路 - 链表实现

本文将详细讲解使用C语言编写学生成绩管理系统的思路,并提供完整代码示例,帮助读者学习C语言编程和数据结构应用。

1. 数据结构定义

首先,我们需要定义学生信息的数据结构,使用结构体来存储每个学生的信息,包括姓名、学号、计算机成绩、数学成绩、英语成绩、总分和平均分。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Student { // 声明学生结构体类型
    char Name[10]; // 定义变量 - 姓名
    int Num; // 定义变量 - 学号
    float Computer; // 定义变量 - 计算机成绩
    float Math; // 定义变量 - 数学成绩
    float English; // 定义变量 - 英语成绩
    float Total; // 定义变量 - 总分
    float Ave; // 定义变量 - 平均分
};

为了方便管理学生信息,我们使用链表来存储学生数据。链表中的每个结点存储一个学生信息,并包含指向下一个结点的指针,从而将所有学生信息连接起来。

typedef struct node { // 结点
    struct Student st; // 数据域
    struct node *pnext; // 指针域
} node, *pnode;

2. 功能函数实现

接下来,我们需要编写一些功能函数来实现学生成绩管理系统的基本操作,包括录入、显示、添加、删除、修改、查找和排序。

2.1 录入学生信息函数 Input()

该函数通过动态内存分配为每个学生信息创建一个结点,并将其加入链表,最后返回链表的头结点指针。

pnode Input() {
    int num; // 学生的人数
    node stu; // 学生结构
    pnode phead = (pnode)malloc(sizeof(node)); // 定义头结点并分配内存
    // 判断内存是否为空
    if (NULL == phead) {
        printf("内存分配失败, 程序终止!
");
        exit(-1);
    }
    pnode ptail = phead; // 指向头结点的指针
    ptail->pnext = NULL; // 清空指针域
    printf("请输入学生的人数:");
    scanf("%d", &num);
    int i;
    for (i = 0; i < num; i++) {
        printf("请输入第%d个学生的姓名:", i + 1);
        scanf("%s", stu.st.Name);
        printf("请输入第%d个学生的学号:", i + 1);
        scanf("%d", &stu.st.Num);
        printf("请输入第%d个学生的计算机成绩:", i + 1);
        scanf("%f", &stu.st.Computer);
        printf("请输入第%d个学生的高数成绩:", i + 1);
        scanf("%f", &stu.st.Math);
        printf("请输入第%d个学生的大英成绩:", i + 1);
        scanf("%f", &stu.st.English);
        stu.st.Total = stu.st.Computer + stu.st.Math + stu.st.English; // 计算总分
        stu.st.Ave = stu.st.Total / 3.0f; // 计算平均分
        pnode pnew = (pnode)malloc(sizeof(node)); // 为新节点分配内存
        // 判断内存是否为空
        if (NULL == pnew) {
            printf("内存分配失败, 程序终止!
");
            exit(-1);
        }
        pnew->st = stu.st; // 初始化结点的数据域
        ptail->pnext = pnew; // 将新结点挂到老结点后
        pnew->pnext = NULL; // 清空新结点的指针域
        ptail = pnew; // 将 ptail 移到新结点上
    }
    return phead;
}

2.2 显示学生信息函数 Show()

该函数通过遍历链表,输出每个学生的信息。

void Show(pnode phead) { // 显示学生信息函数编写
    pnode p = phead->pnext; // 定义一个指针用于遍历学生信息
    printf("姓名  学号 计算机 高数  大英 总分 平均分\n");
    while (NULL != p) {
        printf("%s    %d    %g    %g    %g   %g    %g\n", p->st.Name, p->st.Num, p->st.Computer, p->st.Math, p->st.English, p->st.Total, p->st.Ave);
        p = p->pnext;
    }
}

2.3 增加学生信息函数 Add()

该函数要求用户输入要插入的位置和学生信息,并将其插入链表的指定位置。

void Add(pnode phead) { // 增加学生信息函数编写
    pnode p = phead;
    int i = 0;
    struct Student stu; // 学生结构体
    int loc; // 插入结点的位置
    printf("请输入插入学生的位置:");
    scanf("%d", &loc);
    while (NULL != p && i < loc - 1) {
        p = p->pnext;
        i++;
    }
    if (NULL == p || i > loc) {
        printf("插入结点的位置不存在!\n");
        return;
    }
    printf("你将在第%d个学生后面插入一个学生\n", loc - 1);
    printf("请输入第%d个学生的姓名:", loc);
    scanf("%s", stu.Name);
    printf("请输入第%d个学生的学号:", loc);
    scanf("%d", &stu.Num);
    printf("请输入第%d个学生的计算机成绩:", loc);
    scanf("%f", &stu.Computer);
    printf("请输入第%d个学生的高数成绩:", loc);
    scanf("%f", &stu.Math);
    printf("请输入第%d个学生的大英成绩:", loc);
    scanf("%f", &stu.English);
    stu.Total = stu.Computer + stu.Math + stu.English; // 计算总分
    stu.Ave = stu.Total / 3.0f; // 计算平均分
    pnode pnew = (pnode)malloc(sizeof(node));
    if (NULL == pnew) {
        printf("动态内存分配失败, 程序终止!\n");
        exit(-1);
    }
    pnew->st = stu;
    pnode q = p->pnext;
    p->pnext = pnew;
    pnew->pnext = q;
}

2.4 删除学生信息函数 Delete()

该函数要求用户输入要删除的学生编号,并将其从链表中删除。

void Delete(pnode pHead) { // 删除学生信息函数编写
    pnode p = pHead;
    int i = 0;
    int loc;
    printf("请输入你需要删除的学生的编号:");
    scanf("%d", &loc);
    while (NULL != p->pnext && i < loc - 1) {
        p = p->pnext;
        i++;
    }
    if (NULL == p->pnext || i > loc - 1) {
        printf("没找到需要删除的学生的编号!\n");
        return;
    }
    pnode q = p->pnext;
    p->pnext = q->pnext;
    free(q);
    q = NULL;
    printf("你已经成功删除了第%d个学生的信息!\n", loc);
}

2.5 修改学生信息函数 Change()

该函数要求用户输入要修改的学生姓名,并修改该学生的信息。

void Change(pnode phead) { // 修改学生信息函数编写
    char Name[10];
    printf("请输入你需要修改的学生的姓名:");
    scanf("%s", Name);
    pnode p = phead->pnext; // 定义一个指针用于遍历学生信息
    while (NULL != p) {
        if (0 == strcmp(Name, p->st.Name)) {
            printf(" 姓名  学号 计算机 高数  大英 总分 平均分\n");
            printf(" 修改前的学生信息!\n");
            printf("%s    %d    %g    %g    %g   %g    %g\n", p->st.Name, p->st.Num, p->st.Computer, p->st.Math, p->st.English, p->st.Total, p->st.Ave);
            system("pause");
            system("cls"); // 清屏
            printf(" 请输入新的学生姓名:");
            scanf("%s", p->st.Name);
            printf(" 请输入新的学生学号:");
            scanf("%d", &p->st.Num);
            printf(" 请输入新的学生的计算机成绩:");
            scanf("%f", &p->st.Computer);
            printf(" 请输入新的学生的高数成绩:");
            scanf("%f", &p->st.Math);
            printf(" 请输入新的学生的大英成绩:");
            scanf("%f", &p->st.English);
            p->st.Total = p->st.Computer + p->st.Math + p->st.English; // 计算总分
            p->st.Ave = p->st.Total / 3.0f; // 计算平均分
            break;
        }
        p = p->pnext;
    }
}

2.6 查找学生信息函数 Search()

该函数要求用户输入要查找的学生姓名,并输出该学生的信息。

void Search(pnode pHead) {
    char Name[10];
    printf("请输入你需要查找的学生的姓名:");
    scanf("%s", Name);
    pnode p = pHead->pnext;
    printf("姓名  学号 计算机 高数  大英 总分 平均分\n");
    while (NULL != p) {
        if (0 == strcmp(Name, p->st.Name)) {
            printf("%s    %d    %g    %g    %g   %g    %g\n", p->st.Name, p->st.Num, p->st.Computer, p->st.Math, p->st.English, p->st.Total, p->st.Ave);
        }
        p = p->pnext;
    }
}

2.7 总分排序函数 Sort()

该函数通过遍历链表,比较相邻两个学生的总分大小,将总分大的学生位置交换,实现学生信息按总分降序排序。

void Sort(pnode phead) {
    pnode p, q; // 定义两个指针
    node temp;
    for (p = phead->pnext; NULL != p; p = p->pnext) {
        for (q = p->pnext; NULL != q; q = q->pnext) {
            if (p->st.Total < q->st.Total) { // 当前一个学生的总分小于后一个学生的总分时
                temp.st = p->st; // 交换学生的位置
                p->st = q->st;
                q->st = temp.st;
            }
        }
    }
}

3. 主函数 main()

在主函数中,我们通过循环读入用户的操作命令,根据不同的命令调用相应的函数来实现学生成绩管理系统的功能。

int main() {
    system("color F0"); // 白底黑色
    printf("\t\t\t|           《C语言课程设计》           |\n"); // 进入时界面
    printf("\t\t\t|            学生成绩管理系统             |\n");
    printf("\t\t\t|            学院:国防教育学院           |\n");
    printf("\t\t\t|            专业:电气自动化             |\n");
    printf("\t\t\t|            班级:2240804               |\n");
    printf("\t\t\t|            姓名:胡霄宇                 |\n");
    printf("\t\t\t|            学号:2022320092           |\n");
    int Item; // 保存操作命令
    pnode phead = NULL; // 定义一个指针
    while (1) {
        printf("\n\n");
        printf("\t\t\t============================================\n"); // 操作界面
        printf("\t\t\t|                                          |\n");
        printf("\t\t\t|          欢迎来到学生成绩管理系统        |\n");
        printf("\t\t\t|                                          |\n");
        printf("\t\t\t|==========================================|\n");
        printf("\t\t\t|            请选择要操作的命令            |\n");
        printf("\t\t\t                                           \n");
        printf("\t\t\t              1.录入学生信息              \n");
        printf("\t\t\t              2.显示学生信息              \n");
        printf("\t\t\t              3.增加学生信息              \n");
        printf("\t\t\t              4.删除学生信息              \n");
        printf("\t\t\t              5.修改学生信息              \n");
        printf("\t\t\t              6.查找学生信息              \n");
        printf("\t\t\t              7.按总分排序                \n");
        printf("\t\t\t              8.退出                      \n");
        printf("请选择操作命令:");
        scanf("%d", &Item); // 赋值
        system("cls"); // 清屏
        switch (Item) {
            case 1: // 录入学生信息
            {
                phead = Input(); // 引用函数
            }
            break;
            case 2: // 显示学生信息
            {
                Show(phead); // 引用函数
            }
            break;
            case 3: // 增加学生信息
            {
                Add(phead); // 引用函数
            }
            break;
            case 4: // 删除学生信息
            {
                Delete(phead); // 引用函数
            }
            break;
            case 5: // 修改学生信息
            {
                Change(phead); // 引用函数
            }
            break;
            case 6: // 查找学生信息
            {
                Search(phead); // 引用函数
            }
            break;
            case 7: // 总分排序
            {
                Sort(phead);
                Show(phead);
            }
            case 8:
            {
                printf("程序已退出\n");
                return 0;
            }
            default: printf("输入无效请重新输入"); break;
        }
    }
    system("pause");
}

4. 总结

本文介绍了使用C语言编写学生成绩管理系统的基本思路,并提供了完整代码示例。通过学习本例,读者可以了解到如何使用C语言进行数据结构定义和操作,以及如何编写功能函数来实现程序功能。此外,读者还可以根据自己的需求扩展功能,例如添加保存数据到文件、从文件读取数据等功能,进一步提高程序的实用性。

C语言学生成绩管理系统设计思路 - 链表实现

原文地址: https://www.cveoy.top/t/topic/osmM 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录