基于C语言的Linux学生管理系统设计课程设计

一、课程设计的内容 

 课程设计题目:《学生管理系统设计》

 在现今信息时代,生活速度的加快,使得人们越来越向信息化、智能化、数字化方向开展, 学生信息管理系统是一个由人、计算机等组成的能进展信息的收集、传递、储存、加工、维护和使用的系统 ,必然能代替过去大量、繁杂的手工操作。

通过本课程设计,运用Linux相关数据构造方法,使用数组和应用。

二、功能描述

构建一个学生管理系统,包含以下信息:

1、输入学生信息,包括学号、姓名、班级

2、输入学生成绩(包括语文、数学、英语),并计算学生成绩的总分和平均分

3、按照总分进展排序

4、查询学生信息

5、修改学生信息

6、增加学生信息

7、删除学生信息

8、退出系统

并且有一个清晰的界面来调用各个功能。

三、概要设计

学生管理系统 

├── 输入学生信息 

│   └── addStudent() 

├── 按总分排序和输出学生信息 

│   └── sortAndPrintStudents() 

├── 查询学生信息 

│   └── searchStudent() 

├── 修改学生信息 

│   └── modifyStudent() 

├── 删除学生信息 

│   └── deleteStudent() 

└── 退出系统

创新功能:制作了编译所用到的makefile文件

四、详细设计

代码整体分为四个模块,分别为输入学生信息模块、查询学生信息模块、修改学生信息模块和删除学生信息模块。同时还制作了Makefile文件,使用Makefile可以提高开发效率,简化编译过程,便于管理和协作。

1、输入学生信息模块:这个模块实现了输入学生信息的功能。

实现过程:

定义了一个名为addStudent()的函数,用于向学生数组中添加新的学生信息。

函数首先检查当前学生数量numStudents是否已达到最大学生数量MAX_STUDENTS。如果达到最大数量,函数会打印一条提示信息,并立即返回,无法添加更多的学生。

如果当前学生数量还未达到最大数量,则会创建一个名为 newStudent的临时Student结构体变量,用于存储新学生的信息。

然后,函数会通过输入让用户逐个输入学生的学号、姓名、班级以及语文、数学、英语的成绩,并将输入的值存储到newStudent的相应成员变量中。

接下来,函数会根据语文、数学、英语成绩计算学生的总分 totalScore,并计算平均分averageScore。

随后,函数将newStudent存储到学生数组students的下一个位置,然后通过递增 numStudents,维护已添加学生的数量。

如果输入的学号,与先前输入的学号一致,显示输入学号重复。

最后,函数会打印一条提示信息,表示学生信息添加成功。

这个函数的作用是添加新的学生信息到数组中,扩充学生信息的存储,并更新学生数量。

算法描述:

所用到的数据结构:使用结构体来表示学生的信息并存储在一个数组中。

2、查询学生信息模块:这个模块实现了查询学生信息的功能。

实现过程:

定义了一个名为 searchStudent() 的函数,用于查询学生信息。函数首先会要求用户选择查询方式,可以通过学号查询或者通过姓名查询。

根据用户的选择,函数使用 switch 语句来执行相应的查询逻辑。

若用户选择1,表示通过学号查询。函数会要求用户输入要查询的学生学号,然后使用一个循环遍历学生数组,查找与输入学号匹配的学生。如果找到匹配的学生,会将其信息打印出来,并将 found 标志设置为1,表示找到了匹配的学生。

若用户选择2,表示通过姓名查询。函数会要求用户输入要查询的学生姓名,然后使用一个循环遍历学生数组,通过strcmp()函数将输入的姓名与学生数组中的姓名进行比较,找到匹配的学生。如果找到匹配的学生,会将其信息打印出来,并将 found 标志设置为1。

若用户选择3,表示退出查询,此时直接跳出 switch 语句。

若用户选择其他选项,则打印出无效选择的提示。

最后,根据 found 标志的值,判断是否找到了匹配的学生信息。如果没有找到,则打印出相应的提示信息。

算法描述:

所用到的数据结构:使用结构体数组来存储学生信息。

3、修改学生信息模块:这个模块实现了修改学生信息的功能。

实现过程:

定义了一个名为modifyStudent()的函数,用于修改学生信息。函数首先会要求用户输入要修改的学生学号,然后使用一个循环遍历学生数组,查找与输入学号匹配的学生。

如果找到匹配的学生,会将found标志设置为1,表示找到了匹配的学生。然后,函数会要求用户输入要修改后的学生姓名、班级以及语文、数学和英语成绩。这些输入会直接修改对应学生结构体中的字段值。修改后会通过计算重新计算学生的总分和平均分,并将修改成功的提示打印出来。

如果没有找到匹配的学生,会通过判断 found 标志的值为0来输出未找到匹配的学生信息的提示。

算法描述:

所用到的数据结构:可以使用结构体数组来存储学生信息。

4、删除学生信息模块:这个模块实现了删除学生信息的功能。

实现过程:

定义了一个名为deleteStudent()的函数,用于删除学生信息。函数首先会要求用户输入要删除的学生学号,然后使用一个循环遍历学生数组,查找与输入学号匹配的学生。

如果找到匹配的学生,将会通过循环将其后面的学生信息向前移动,以覆盖要删除的学生信息。然后,将学生数量numStudents减一,表示删除了一个学生。最后,输出学生信息删除成功的提示。

如果没有找到匹配的学生,会通过判断 found 标志的值为 0 来输出未找到匹配的学生信息的提示。

算法描述:

所用到的数据结构:可以使用结构体数组来存储学生信息。

5、Makefile文件:使用Makefile可以提高开发效率,简化编译过程,便于管理和协作。

实现过程:

Makefile文件,用于编译和链接C语言源代码以生成可执行文件。以下是对Makefile的逐行解释:

sms: sms.o:这一行定义了一个规则,指定如何生成名为"sms"的可执行文件。在这个规则中,"sms"依赖于"sms.o"这个目标文件。

gcc sms.o -o sms:这是上一行规则的命令部分,使用GCC编译器将"sms.o"链接为名为"sms"的可执行文件。

sms.o: sms.c:这一行定义了另一个规则,指定如何生成名为"sms.o"的目标文件。在这个规则中,"sms.o"依赖于"sms.c"这个源文件。

gcc -c sms.c -o sms.o -std=c99:这是上一行规则的命令部分,使用GCC编译器将"sms.c"编译为名为"sms.o"的目标文件。-c选项表示只编译,不链接。-std=c99选项指定使用C99标准。

clean::这一行定义了一个名为"clean"的伪目标,用于执行清理操作。

rm -f sms:这是上一行规则的命令部分,使用rm命令删除名为"sms"的可执行文件。-f选项表示强制删除,即使文件不存在也不会报错。

rm -f *.o:这是上一行规则的另一个命令,使用rm命令删除所有扩展名为".o"的目标文件。这也是一个清理操作,用于清除编译过程中生成的目标文件。

总体来说,这个Makefile文件包含了两个规则:一个用于编译和链接源代码生成可执行文件,另一个用于清理生成的可执行文件和目标文件。可以通过在终端中运行make命令来执行Makefile中的规则,生成可执行文件。运行make clean命令可以执行清理操作。

主要源代码:

sms:sms.o

    gcc sms.o -o sms

sms.o:sms.c

    gcc -c sms.c -o sms.o -std=c99

clean:

    rm -f sms

    rm -f *.o

五、测试结果

1、使用makefile文件,对文档进行编译。

2、生成可执行文件。

3、运行可执行文件。

4、添加三名学生的信息。

5、如果输入的学号信息相同,显示输入的学号重复。

6、按照总成绩从高分到低分输出学生信息。

7、按照学号和姓名查询两种方式查询学生信息。

8、修改其中一位学生信息。

9、删除其中一位学生信息。

10、输出学生信息,验证是否成功。

11、退出系统。

12、使用make clean指令,删除可执行文件。

六、代码

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

#define MAX_STUDENTS 1000

struct Student {
	long int id;
	char name[200];
	char class[200];
	int scores[3];  
	int totalScore; 
	float averageScore;  
};

struct Student students[MAX_STUDENTS]; 
int numStudents = 0; 

int isStudentIdDuplicate(long id) {
    for (int i = 0; i < numStudents; i++) {
        if (students[i].id == id) {
            return 1; 
        }
    }
    return 0; 
}

void addStudent() {
    if (numStudents >= MAX_STUDENTS) {
        printf("已达到最大学生数量,无法添加更多学生。\n");
        return;
    }

    struct Student newStudent;
    printf("请输入学生学号:");
    scanf("%ld", &newStudent.id);

    if (isStudentIdDuplicate(newStudent.id)) {
        printf("学号输入重复,请重新输入。\n");
        return;
    }

    printf("请输入学生姓名:");
    scanf("%s", newStudent.name);
    printf("请输入学生班级:");
    scanf("%s", newStudent.class);
    printf("请输入学生语文成绩:");
    scanf("%d", &newStudent.scores[0]);
    printf("请输入学生数学成绩:");
    scanf("%d", &newStudent.scores[1]);
    printf("请输入学生英语成绩:");
    scanf("%d", &newStudent.scores[2]);

    newStudent.totalScore = newStudent.scores[0] + newStudent.scores[1] + newStudent.scores[2];
    newStudent.averageScore = newStudent.totalScore / 3.0;

    students[numStudents] = newStudent;
    numStudents++;

    printf("学生信息添加成功。\n");
}

int compareStudents(const void *a, const void *b) {
    struct Student *studentA = (struct Student *)a;
    struct Student *studentB = (struct Student *)b;
    return studentB->totalScore - studentA->totalScore;
}

void sortAndPrintStudents() {
    qsort(students, numStudents, sizeof(struct Student), compareStudents);

    printf("按总分排序后的学生信息:\n");
    for (int i = 0; i < numStudents; i++) {
        struct Student *student = &students[i];
        printf("学号:%ld 姓名:%s 班级:%s 语文:%d 数学:%d 英语:%d 总分:%d 平均分:%.2f\n", student->id, student->name, student->class,student->scores[0], student->scores[1], student->scores[2], student->totalScore, student->averageScore);
    }
}

void searchStudent() {
    int choice;
    printf("请选择查询方式:\n");
    printf("1、通过学号查询\n");
    printf("2、通过姓名查询\n");
    printf("3、退出本次查询\n");
    printf("请选择:");
    scanf("%d", &choice);

    long int searchId;
    char searchName[200];
    int found = 0;

    switch (choice) {
        case 1:
            printf("请输入学生学号:");
            scanf("%ld", &searchId);
            for (int i = 0; i < numStudents; i++) {
                if (students[i].id == searchId) {
                    struct Student *student = &students[i];
                    printf("学号:%ld 姓名:%s 班级:%s 语文:%d 数学:%d 英语:%d 总分:%d 平均分:%.2f\n", student->id, student->name, student->class,student->scores[0], student->scores[1], student->scores[2], student->totalScore, student->averageScore);
                    found = 1;
                    break;
                }
            }
            break;
        case 2:
            printf("请输入学生姓名:");
            scanf("%s", searchName);
            for (int i = 0; i < numStudents; i++) {
                if (strcmp(students[i].name, searchName) == 0) {
                    struct Student *student = &students[i];
                    printf("学号:%ld 姓名:%s 班级:%s 语文:%d 数学:%d 英语:%d 总分:%d 平均分:%.2f\n", student->id, student->name, student->class,student->scores[0], student->scores[1], student->scores[2], student->totalScore, student->averageScore);
                    found = 1;
                    break;
                }
            }
            break;
	case 3:
		printf("未选择退出查询。\n");
		found = 1;
		break;
        default:
            printf("无效的选择。\n");
    }

    if (!found) {
        printf("未找到匹配的学生信息。\n");
    }
}

void modifyStudent() {
    long int modifyId;
    printf("请输入要修改的学生学号:");
    scanf("%ld", &modifyId);

    int found = 0;
    for (int i = 0; i < numStudents; i++) {
        if (students[i].id == modifyId) {
            struct Student *student = &students[i];
            printf("请输入修改后的学生姓名:");
            scanf("%s", student->name);
            printf("请输入修改后的学生班级:");
            scanf("%s", student->class);
            printf("请输入修改后的学生语文成绩:");
            scanf("%d", &student->scores[0]);
            printf("请输入修改后的学生数学成绩:");
            scanf("%d", &student->scores[1]);
            printf("请输入修改后的学生英语成绩:");
            scanf("%d", &student->scores[2]);
            student->totalScore = student->scores[0] + student->scores[1] + student->scores[2];
            student->averageScore = student->totalScore / 3.0;
            printf("学生信息修改成功。\n");
            found = 1;
            break;
        }
    }

    if (!found) {
        printf("未找到匹配的学生信息。\n");
    }
}

void deleteStudent() {
    long int deleteId;
    printf("请输入要删除的学生学号:");
    scanf("%ld", &deleteId);

    int found = 0;
    for (int i = 0; i < numStudents; i++) {
        if (students[i].id == deleteId) {
            for (int j = i; j < numStudents - 1; j++) {
                students[j] = students[j + 1];
            }
            numStudents--;
            printf("学生信息删除成功。\n");
            found = 1;
            break;
        }
    }

    if (!found) {
        printf("未找到匹配的学生信息。\n");
    }
}

int main() {
    int choice;
    while (1) {
        printf("----------------------\n");
        printf("学生管理系统\n");
        printf("1、输入学生信息\n");
        printf("2、按总分排序和输出学生信息\n");
        printf("3、查询学生信息\n");
        printf("4、修改学生信息\n");
        printf("5、删除学生信息\n");
        printf("6、退出系统\n");
        printf("----------------------\n");
        printf("请选择操作:");
        scanf("%d", &choice);

        switch (choice) {
            case 1:
                addStudent();
                break;
            case 2:
                sortAndPrintStudents();
                break;
            case 3:
                searchStudent();
                break;
            case 4:
                modifyStudent();
                break;
            case 5:
                deleteStudent();
                break;
            case 6:
                exit(0);
            default:
                printf("无效的选择。\n");
        }
    }

    return 0;
}

  • 6
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SkyQi_奇崽

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值