一、课程设计的内容
课程设计题目:《学生管理系统设计》
在现今信息时代,生活速度的加快,使得人们越来越向信息化、智能化、数字化方向开展, 学生信息管理系统是一个由人、计算机等组成的能进展信息的收集、传递、储存、加工、维护和使用的系统 ,必然能代替过去大量、繁杂的手工操作。
通过本课程设计,运用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;
}
版权归原作者 SkyQi_奇崽 所有, 如有侵权,请联系我们删除。