# 基于C语言的学生成绩管理系统
# 1 系统分析
此学生成绩管理系统是为管理学生成绩数据的人员提供,为管理学生成绩数据的相关人员提供充足的信息和快捷的查询手段。该系统的编写目的是提高学生成绩管理的工作效率,使人们从乏味的数据登记和统计工作中解脱出来,保证工作的准确率。
## 1.1 功能需求
学生学籍管理管理系统是直接面对使用人员的,而使用人员往往对计算机并不时非常熟悉。这就要求系统能够提供良好的用户接口,易用的人机交互界面。要实现这一点,就要求系统应该尽量使用用户熟悉的术语和中文信息的界面;针对用户可能出现的使用问题,要提供足够的在线帮助,缩短用户对系统熟悉的过程。
学生学籍管理系统中涉及到的数据是学校相当重要的信息,系统要提供方便的手段供系统护人员进行数据的备份,日常的安全管理,系统意外崩溃时数据的恢复等工作。
## 1.2 非功能性需求
- **正确性**:不允许出现业务错误
- **健壮性**:在系统出现故障时,系统必须提供相应的数据保护措施,不能丢失 数据,并提供从新恢复正常工作的机制
- **可靠性**:除电源硬件、操作系统外不允许异常退出或崩溃
- **性能、效率**:系统处理业务时间最迟时间小于等于1秒
- **易用性**:使用简单,操作方便
- **安全性**:用户只能通过系统操作后台数据,不能够对数据库进行直接操作
- **可扩展性**:可在当前需求基础之上进行功能上的扩展
- **兼容性**:能够运行在多台主机上
- **可移植性**:可以够运行在WindowsXP以上Windows 系列操作系统平台上
## 1.3 用户界面
- 采用DOS的通用图形界面,用户界面友好
- 界面具有一致性,界面规范遵循DOS软件界面的规范
- 提供错误信息处理
- 提供信息提示,提示当前用户的误操作信息和指示信息
- 提供方便的退出系统的方法
- 用户对程序的维护,最好要有备份
# 2 系统设计
此系统是的设计采用模块化的设计方法,根据使用者的选择逐步调用。采用模块化的程序设计方法,即将较大的任务按照一定的原则分为一个个较小的任务,然后分别设计各个小任务。需要注意的是划分出来的模块应该相对独立但又相关,且容易理解。可以用模块化层次结构图(即模块图)来分析其任务的划分,一般从上到下进行,最上面一层是主模块,下面各层是其上一层模块的逐步细化描述。
## 2.1 体系结构设计
创建结构体数组来储存学生的信息,创建一个switch函语句创建一个整体框架,case下包括各个主干功能,某些主干功能也用switch来包括分支功能,程序的各个功能都用函数表示。
## 2.2 数据设计
定义全局结构体方便调用,MAX_STU是最大学生数量,方便后期开通增值服务。
```c
struct Student //定义一个学生结构体
{
char names[30]; //姓名
long long stu_id; //学号
int stu_class; //班级
double lesson1; //高等数学·上
double lesson2; //英语视听说
double lesson3; //大学计算机基础
double lesson4; //软件工程导论
double lesson5; //C语言程序设计
double avg;
}student[MAX_STU];
char password_real[30] = "123456"; //在此处设置密码
int now_index=0; //开始录入第now_index个学生
int i; //定义整形i用来for循环
double avg1=0,avg2=0,avg3=0,avg4=0,avg5=0,avg0; //为求平均做准备
FILE * fp;
char temp_cls; //清屏函数的临时回车选项
```
## 2.3 模块设计
**模块设计分析图**

# 3 系统实现
模块化的系统实现,参考上述模块设计图。
## 3.1 欢迎模块
```c
void Welcome();
```
介绍公司和慰问用户,使用户能够感受到软件制作团队的认真与用心。在欢迎模块中附加温馨提示,以防给使用者带来不舒适的软件市容体验,另外附加上软件的升级会员版的条件的途径。

## 3.2 密码模块
```c
void password_input(); //定义密码的输入
```
在此程序的欢迎界面之后紧接着是输入密码的界面,输入密码要求输入正确的密码。输入密码的实现是将用户输入的一串字符和系统内本身定义好的字符串进行比较,用strcmp();验证时候相等,如果判断正确,通过进入系统,如果不成立,则进入循环输入状态,直到输入5次为止。累计输入5次错误则退出系统。(密码是123456)
## 3.3 菜单模块
```c
menu();
```
菜单模块的实现主要包括两部分:
- 第一部分是通过printf();函数将菜单选项提供给用户进行选择,根据用户接下来的操作来判定下一步的操作
- 第二部分是根据用户的选项调用已经封装好的各个功能的函数,代码如下。本功能的实现是通过switch();函数来找到与用户输入的功能序号相对应的封装函数。利用goto语句进行抛出异常。其中cls();是请屏函数,它的实现是调用windows.h头文件下的system();来实现
```c
loop_menu:scanf("%d",&menu_id);
switch(menu_id) //选择菜单
{
case 1: stu_add();break;
case 2: stu_output();cls();break;
case 3: stu_find();cls();break;
case 4: stu_revise();cls();break;
case 5: stu_delete();cls();break;
case 6: stu_subsection();cls();break;
case 7: stu_fileClass();break;
case 8: stu_over();cls();break;
default : {
fflush(stdin) ;
printf("您的输入有误,请重新输入:");
goto loop_menu; //循环该菜单
}
```

## 3.4 录入模块
```c
stu_add();
```
录入模块的实现是让用户通过使用空格分隔来录入每一次代码输入的各个不同的值,然后赋予给结构体成员的不同变量。每一次输入之后,提示用户是否继续输入,如果继续输入则重复上述步骤。如果用户输入的内容不符合规定,则给出提示后加入清楚缓冲区的方法fflush(stdin);然后重新录入,直用户输入完毕后使用N\n来结束录入。在本模块中保留输入有误的提示语,并循环到上一步,使系统具有充足的容错性。

## 3.5 输出模块
```c
stu_output();。
```
输出模块首先通过if语句判断是否有学生数据的情况,当全局变量now_index数值恒等于0时代表学生数据为0,所以提示用户不能进行此操作。紧接着回到菜单。如果判断当前软件录入人数大于0,则跳过if语句的ruturn 0操作。此时紧接着调用求平均函数avg_student();来计算每个学生的平均成绩,然后调用排序函数,将学生的成绩降序排列。降序的实现是通过冒泡排序法对全局结构体成员进行降序排列,然后在输出模块的下一部分for循环顺序输出,依次实现降序输出学生成绩的目的。在最后调用avg_lesson();函数来求取没课成绩的平均成绩并在输出模块的下方输出。avg_lesson();的实现是定义全局变量总成绩,将之与当前now_index相除求取平均值并通过.2lf保留两位小数。

## 3.6 查找模块
```c
stu_find();
```
查找模块的实现的关键在于查找到对应学生的下标,�