学生管理系统怎么实现?首先要对问题能分析出框架来。这样在之后书写功能时就会对所需要的东西有一个清晰的认知。

        那么,管理系统的任务就是:能删除、查找和修改学生信息,能进行排序、能打印信息。

        这些都是最基本的功能,把这些功能框架写在一个c源文件里,当作主函数的运行区。
#include"StudentManager.h" enum Option { EXIT, ADD, DEL, SEARCH, MODIFY, SORT,
PRINT }; int main() { int input = 0; //创建人员名单 Student stulist;//人员名单 //初始化人员名单
InitStudent(&stulist); do { menu(); printf("请选择:\n"); scanf_s("%d", &input);
switch(input) { case ADD: AddStudent(&stulist);//修改一定传地址 break; case DEL:
DelStudent(&stulist); break; case SEARCH:
SearchStudent(&stulist);//可以传值,但传地址效率更高 break; case MODIFY:
ModifyStudent(&stulist); break; case SORT: SortStudent(&stulist); break; case
PRINT: PrintStulist(&stulist); break; case EXIT: printf("退出管理系统\n"); default:
break; } } while (input); SaveFile(&stulist); }
========================================================================= 

        而后,是单独的一个文件,实现对所使用函数的声明,以便让业务逻辑更加分明:(同时尽量在这里就把所需要的存储类型定义了,这样写功能函数的时候会更加的清晰)
#pragma once #include<stdio.h> #include<stdlib.h> #include<string.h> //结构体定义
typedef struct StuInfo { //(1)每个学生的个人信息包括:姓名、学号、籍贯、年龄、数学、英语、物理成绩 char name[15];
char address[20]; char ID[15]; int age; int score[3]; int sum; int order;
}StuInfo; //对结构体进行封装 typedef struct Student { StuInfo data[100]; //存放的人员信息 int
size; //记录当前的人数 }Student; int FindByName(Student* pc, char name[]); void
InitStudent(Student* pc); void AddStudent(Student* pc); void
DelStudent(Student* pc); void SearchStudent(Student* pc); void
ModifyStudent(Student* pc); void SortStudent(Student* pc); void
SaveFile(Student* pc); void PrintStulist(const Student* pc); void menu();
 =========================================================================

        之后,就是对函数功能的实现了,在实现功能之前,我们已经确定自己写的学生信息存储方式是什么。所以,就是函数功能的实现。

首先最基础的是菜单界面:
//显示菜单界面 void menu() { printf("---------------\n"); printf("1.增 2.删 \n");
printf("3.查 4.改 \n"); printf("5.排 6.打印 \n"); printf(" 0.退出 \n");
printf("---------------\n"); }
========================================================================= 

    然后写一个函数来初始化空间(不多解释):
//初始化数据,以便使用 void InitStudent(Student* pc) { pc->size = 0; memset(pc->data, 0,
sizeof(pc->data));//初始化所有数据为0 }
        之后就是一些功能的实现,比如我们先实现一个打印的功能,因为打印功能的代码在其他功能里也能使用和体现(例如查找):

        指针pc想要解引用地址,就需要使用' -> ',其他的则是' .
'。所以打印信息的操作就一目了然了,首先指针解引用取单个学生信息,然后结构体再去取出相应的信息数据来。
//打印信息 void PrintStulist(const Student* pc) { int i = 0; //打印标题
printf("%-10s\t%-10s\t%-10s\t%-10s\t%-20s\n", "姓名", "学号", "籍贯", "年龄",
"成绩:数学、英语、物理、"); for (i = 0; i < pc->size; i++) {
printf("%-10s\t%-10s\t%-10s\t%-10d\t%d\t%d\t%d\n", pc->data[i].name,
pc->data[i].ID, pc->data[i].address, pc->data[i].age, pc->data[i].score[0],
pc->data[i].score[1], pc->data[i].score[2]);//输入的三科成绩 } }
       
在这里,需要简单的说明一下这个函数,使用const只读属性是因为我们接受的是学生名单的信息,但为了保证学生名单信息不会被误操作(除打印以外的操作),所以加上了const。那么可能有人会问,既然害怕被修改,为什么不直接定义一个普通变量接受学生信息,而要使用指针?那么请思考一下:
指针接受的是地址,普通变量接受的是全部的信息,哪个效率更高呢?当然是传址的效率高。

=========================================================================

       
而后是添加的功能,一个新学生来到了班级,得重新录入信息吧,所以添加的功能需要一些什么?当然就是对应的信息去做修改(此处定义的学生名单进行封装时,定义的是100,当然,你也可以选择#define宏定义,以便后期维护):
//增加人员信息 void AddStudent(Student* pc) { if (pc->size == 100) {
printf("名单已满,无法添加\n"); return; } //增加信息 printf("请输入名字:\n"); scanf_s("%s",
pc->data[pc->size].name, 15); printf("请输入学号:\n"); scanf_s("%s",
pc->data[pc->size].ID, 15); printf("请输入籍贯:\n"); scanf_s("%s",
pc->data[pc->size].address, 20); printf("请输入年龄:\n"); scanf_s("%d",
&(pc->data[pc->size].age)); printf("请输入数学、英语、物理成绩:\n"); scanf_s("%d %d %d",
&(pc->data[pc->size].score[0]), &(pc->data[pc->size].score[1]),
&(pc->data[pc->size].score[2])); pc->size++; printf("信息添加成功\n"); }
        添加的操作跟打印还是很相像的,就不多做解释。

=========================================================================

        那么,看看剩下的几个功能,其中有修改、删除和查找,我们仔细分析一下这三个功能,都需要定向的找到某个学生,所以,我们先写一个查找的功能出来(
查找只能顺序查找,一个一个去看哪个符合条件,所以用for或者while):
//定义一个查找的功能,以便删除,查找使用 int FindByName(Student* pc, char name[]) { int i = 0;
for (i = 0; i < pc->size; i++) { if ((strcmp(pc->data[i].name, name)) == 0) {
return i; } } return -1; }
        这里查找使用的是姓名查找,你也可以去更改查找的功能实现更高级一点的操作,比如根据成绩找人,根据ID找人(本质都一样)。

=========================================================================

        根据这个查找的功能,我们就可以去实现删除和修改操作了,当一个学生犯下滔天大罪,那就得退学咯,所以接下来实现一下删除:

        这里要注意,因为是对学生的信息进行了更改,所以必须传地址。
//删除人员信息 void DelStudent(Student* pc) { char name[15] = { 0 }; if (pc->size ==
0) { printf("名单已空,没有信息可以删除\n"); return; } //1.查找要删除的人 printf("请输入要删除的人:\n");
scanf_s("%s", name, 15); int position = FindByName(pc, name); /* 有/没有 --> 2. 删除
*/ if (position == -1) { printf("要删除的人不存在"); return; } //删除 int i = 0; for (i =
position; i < pc->size - 1; i++)//size-1是因为左后一个元素没必要被覆盖,后面代码删除 { pc->data[i] =
pc->data[i + 1];//依次覆盖实现向前移动和删除 } pc->size--; printf("删除成功\n"); }
       
删除的实现也算是相当简单了,因为实际上就等于是找到这个学生,然后把整个表格向前移动,直接覆盖这个学生就行(没办法,顺序表的缺陷就是删除操作时间复杂度高),同时,注意书写时也要判断学生存不存在。

       
那么查找操作呢?我们上面写的关于查找的功能,只是程序找到了这个人的信息,真正需要去查找,总得去查看一下这个人的信息吧。班里学生想知道自己的信息,找老师去查,肯定是需要输出信息的,所以这里也摘下了打印的一部分代码:
//查找指定的人员 --> 借用了删除人员的代码以及打印信息的代码 void SearchStudent(Student* pc) { char
name[15] = { 0 }; printf("请输入要查找的人:\n"); scanf_s("%s", name, 15); int position
= FindByName(pc, name); if (position == -1) { printf("要查找的人不存在"); return;
}//跟删除的判断一样的代码 else//去打印找代码,注意更改一些内容 {
printf("%-10s\t%-10s\t%-10s\t%-10s\t%-20s\n", "姓名", "学号", "籍贯", "年龄",
"成绩:数学、英语、物理、"); printf("%-10s\t%-10s\t%-10s\t%-10d\t%d\t%d\t%d\n",
pc->data[position].name, pc->data[position].ID, pc->data[position].address,
pc->data[position].age, pc->data[position].score[0],
pc->data[position].score[1], pc->data[position].score[2]);//从打印那里摘来的代码 } }
        所以,基本上只要理解了最前面几个代码,剩下的也就迎刃而解了。那么我们还剩下跟查找有关的修改功能:
//修改指定的人员信息 --> 借用了查找的代码以及添加的代码 void ModifyStudent(Student* pc)//使用查找的代码进行改造 {
char name[15] = { 0 }; printf("请输入要修改的人:\n"); scanf_s("%s", name, 15); int
position = FindByName(pc, name); if (position == -1) { printf("要修改的人不存在");
return; }//跟删除的判断一样的代码 else//注意,这里是跟添加一样的代码 { printf("请输入名字:\n"); scanf_s("%s",
pc->data[position].name, 15); printf("请输入学号:\n"); scanf_s("%s",
pc->data[position].ID, 15); printf("请输入籍贯:\n"); scanf_s("%s",
pc->data[position].address, 20); printf("请输入年龄:\n"); scanf_s("%d",
&(pc->data[position].age)); printf("请输入数学、英语、物理成绩:\n"); scanf_s("%d %d %d",
&(pc->data[position].score[0]), &(pc->data[position].score[1]),
&(pc->data[position].score[2])); printf("信息修改成功\n"); } }
       
发现了吗?跟添加信息又有点像。总之,跟查找有关的函数功能基本上全实现了,那么还剩下排序的功能没有实现,由于排序的功能与查找关系就不大了,所以列为下一个大块。

=========================================================================

       
排序,我们能用到的排序其实有很多算法,比如选择排序、冒泡排序、插入排序、快速排序等等,这里就使用了一个更容易理解的插入排序算法来实现对学生的排序(算总分来排序):
//对人员进行排序 void SortStudent(Student* pc) { for (int i = 0; i < pc->size; i++) {
pc->data[i].sum = pc->data[i].score[0] + pc->data[i].score[1] +
pc->data[i].score[2]; } printf("总分排序结果:\n");//使用插入排序实现此功能 StuInfo p; int i, j;
for (i = 1; i < pc->size; i++) if (pc->data[i].sum > pc->data[i - 1].sum) { p =
pc->data[i]; for (j = i - 1; j >= 0 && pc->data[j].sum < p.sum; j--) pc->data[j
+ 1] = pc->data[j]; pc->data[j + 1] = p; } StuInfo* t; i = 0; for (t =
pc->data; t < pc->data + pc->size; t++) { pc->data[i].order = i + 1; i++; }
//把排序之后的名单打印出来 printf("%-10s\t%-10s\t%-10s\t%-10s\t%-20s\n", "姓名", "学号", "籍贯",
"年龄", "成绩:数学、英语、物理、"); for (int i = 0; i < pc->size; i++) {
printf("%-10s\t%-10s\t%-10s\t%-10d\t%d\t%d\t%d\n", pc->data[i].name,
pc->data[i].ID, pc->data[i].address, pc->data[i].age, pc->data[i].score[0],
pc->data[i].score[1], pc->data[i].score[2]);//输入的三科成绩 } }
       
那么,这段代码就只稍微解释一下所使用的排序的算法思路。插入排序,就是找到最大的那个值(得循环一遍才能找到),然后放到前面去,循环下来,就得到了一个顺序。具体的算法,等日后笔者再写一篇CSDN讲解一下吧,毕竟排序的内容还是很多的。

        同时,这个函数也使用了打印的代码,毕竟,排完序得让别人看见嘛,所以也打印一下整个学生名单的信息。

       
写到这里,所有的功能基本就已经实现了。但是鉴于学生的信息最终可能要保存到文件里,以便日后使用,所以,这里又补了一个简单的文件保存的函数,当然,如果读者想实现读文件来写管理系统,那也是可以的:
//存储文件 void SaveFile(Student* pc) { FILE* fp = NULL; fopen_s(&fp,
"studentInfo.txt", "wt+"); //b表示以二进制方式打开文件 if (fp == NULL) //打开文件失败,返回错误信息 {
printf("open file for write error\n"); } int i = 0; for (i = 0; i < pc->size;
i++) { fprintf(fp, "%-10s\t%-10s\t%-10s\t%-10d\t 三科成绩:%d\t%d\t%d\n",
pc->data[i].name, pc->data[i].ID, pc->data[i].address, pc->data[i].age,
pc->data[i].score[0], pc->data[i].score[1], pc->data[i].score[2]); }
fclose(fp); fp = NULL; }
        终于,我们的学生管理系统就算时搭建完成了,那么,小火罐们快拿着代码去试一试吧!

技术
©2019-2020 Toolsou All rights reserved,
C语言——qsort函数CSS实现溢出显示省略号网络层协议——ICMP协议C语言小游戏-俄罗斯方块Qt入门教程【基础控件篇】QCalendarWidget日历控件用python来控制wifi连接vue中input框只能输入数字Python内置函数C语言数据结构-顺序表删除重复V2.0.0abaqus质量缩放系数取值_ABAQUS的质量缩放