♻️ 资源
大小: 2.30MB
➡️ 资源下载: https://download.csdn.net/download/s1t16/87472190
https://download.csdn.net/download/s1t16/87472190
学生成绩管理系统
设计任务
本组的项目题目是《学生成绩管理系统》,因此我们的目标是能够建立一个相对独立的,功能较为完善的,界面友好的管理系统,以实现对学生成绩及其他各项信息的管理任务。
基本思路与需求分析
我们的成绩管理系统采用数组的模型来处理成绩及相关各项操作。并且采用不同的函数和从不同的文件中对函数进行调用。我们把设计中主要需要包含的功能模块进行了总结如下:建立文件以存放学生信息,录入学生信息,增加学生记录,显示记录以及显示对相关成绩信息进行各种操作后的结果,文件存储,读取文件,删除记录,修改记录,查询记录。
相应的功能之间的实现框架如下表:

设计要求
1、用 C 语言实现系统,使用多文件方式实现设计;
2、利用流程控制语句、数组、指针、结构体文件等知识实现上述题目的数据结构设计;
3、 系统具有输入、查询,修改,删除,排序等基本功能;
4、 进行简单界面设计,能够实现友好的交互;
5、 具有清晰的程序流程图和数据结构的详细定义;
6、 系统的各个功能模块要求用函数的形式实现;
7、 宏和数据结构等放在头文件中,并使用条件编译。
方案设计
主要算法说明
本程序中出现的算法并不算复杂,本组队员在为解决程序设计过程中遇到的问题而采用。主要算法包括"冒泡排序法"、"差值算法"及"线性方程求解"等。
举例:可以应用冒泡法对学生成绩按某科由高到低进行排序再输出。简要代码举例:
for(i=0;i<N;i++)
for(j=i+1;j<N;j++)
if(stu[i].average<stu[j].average)
{temp=stu[i];stu[i]=stu[j];stu[j]=temp;}
程序框架设计
对程序的开发任务与需要解决的问题的讨论之后,我们初步确定下了开发的总体流程。

系统的功能模块

数据结构设计描述
# define INITIAL_SIZE 100 //数组初始大小
# define INCR_SIZE 50 //数组每次增加的大小
# define NUM_SUBJECT 5 //科目数
struct student_info //结构体
{
char number[15]; //学号
char name[20]; //姓名
char gender[4]; //性别
float score[NUM_SUBJECT];//分别为该学生5门课的成绩
float sum; //总分
float average; //平均分
int index; //名次
};
typedef struct student_info StuInfo;
extern int numStus; //记录的学生数
extern StuInfo* records; //记录学生信息的数组
extern char savedTag; //信息是否已保存的标志,0为已保存,1为保存
extern int arraySize; //数组大小
extern char* subject[];
每个学生信息资料用一个 StuInfo 结构来保存,用 StuInfo 数组全局变量 records 来保存一批学生的信息资料。宏定义 INITIAL_SIZE 表示数组初始大小,当已分配的数组大小不够用的时候,将增加数组大小,INCR_SIZE 为当每次增加的大小。numStus 为全局变量,表示数组中记录的学生数,arraySize 是为数组分配的空间大小。全局变量 sacedTag 是信息是否以保存的标志,当数组内容被保存至文件后,设为"已保存"状态,当数组内容被修改之后,设为"为保存"状态。
函数功能及参数说明、相互调用关系
|-------------------------------------------------------------------------------------------|--------------|---------|
| 源文件 | 函数名或其他成分 | 功 能 |
|
student.c | main | 总控函数 |
| menu_select | 菜单选择 | |
| handle_menu | 菜单处理 | |
| newRecords | 新建学生信息记录 | |
| quit | 结束运行 | |
| add_disp.c add_disp.c | showTable | 打印表头 |
|
getIndex | 按升序排序的位置 | |
| addRecord | 在表尾追加信息 | |
| display | 显示信息 | |
| que_remv_modi.c | removeRecord | 删除制定的记录 |
| findRecord | 查找制定的记录 | |
| queryInfo | 查找制定学生的信息 | |
| copyRecord | 复制记录 | |
| modifyRecord | 修改制定学生信息 | |
| save_load.c | save | 文件储存 |
| load | 文件读取 | |
| sort.c | sortInfo | 排序 |
| student.h | 常数 | 提供常数 |
| 结构声明 | 学生成绩结构 | |
| 库函数及函数原型声明 | 引用库函数及函数 | |
重要变量的定义和作用
student.h
define INITIAL_SIZE 100 //数组初始大小
# define INCR_SIZE 50 //数组每次增加的大小
# define NUM_SUBJECT 5 //科目数
struct student_info
{
char number[15]; //学号
char name[20]; //姓名
char gender[4]; //性别
float score[NUM_SUBJECT];//分别为该学生5门课的成绩
float sum; //总分
float average; //平均分
int index; //名次
};
extern int numStus; //记录的学生数
extern StuInfo* records; //记录学生信息的数组
extern char savedTag; //信息是否已保存的标志,0为已保存,1为保存
extern int arraySize; //数组大小
除此之外还有部分函数内部变量,用作循环和判断条件。
各功能模块的算法处理流程图及相关说明
1.总控函数、菜单文件 student.c

在主函数中,首先使用 malloc 函数分配 INITIAL_SIZE 个 StuInfo 大小的数组给 records,对各个全局变量进行初始化赋值,反复进行菜单处理。cn=atoi(s)用来对 cn 赋值,使之与 case 值对应,以致得到对应的函数。
2.add_disp.c
⑴ 增加信息函数 void addRecord(void)


addRecord 用来在当前表的尾部增加新的信息,这只要将新的信息保存到 recordsnumStus中,然后 numStus 自加 1,完成操作。
增加新信息前,numStus 已经大于或等于 arraySize,使用 realloc 函数重新为 records 分配大小。每增加一个学生信息,就通过总分来计算名次,该学生的名次是总分高于他的学生的总数加 1,并且所有总分小于他的学生的名次均增加 1.
⑵ 显示信息函数 void display(void)
display 用来显示学生信息,通过循环显示从 0 到 numStus-1 个学生的信息。

3.save_load.c
⑴ 文件存储操作函数 int saveRecord(void)
saveRecords 函数,是通过 fwrite 函数一次写入荣 records 开始的 numStus 个 StuInfo 大小的字节。
⑵ 文件读取操作函数 int loadRecords(void)
loadRecord 函数可以连续读入文件,后面增加的文件可以追加到前面的记录数组之后,从而可以作为一个更大的文件存储。
如果要覆盖原来的记录,就先保存原纪录,然后令 numStus 为 0,否则原来的 numStus 不变。在读取文件时,使用 fread 函数,每次读取 sizeof(StuInfo)个字节,存放在数组 recordsnumStus里面,并令 numStus 自加 1,直到读完文件。如果每读入一条之前,numStus 已经大于或等于 arraySize,那么就是用 realloc 函数重新为 records 分配大小为(arraySize+INCR_SIZE)个 StuInfo 的数组然后重新设置 arraySize。读入文件要涉及到重新排名问题,所以调用 getIndex 函数对名次更新。
4.sort.c

5.que_remv_modi.c
⑴ 查找指定记录函数 int findRecord()

⑵ 查询指定信息函数 void queryInfo(void)

改进或增加功能模块说明
1.在 student.c 中添加了一个简单的密码程序
int k=0;
char a[20],n1[20],n2[20];
printf("学生成绩管理系统\n\n");
printf("\t李绍广\n\n");
printf("\n\t请输入设置的密码:");
scanf("%s",n1);
printf("\n\t请再次输入设置的密码:");
scanf("%s",n2);
while(strcmp(n1,n2)>0||strcmp(n1,n2)<0)
{
printf("\n两次密码输入不同,请重新输入。\n\n");
printf("\n\t请输入设置的密码:");
scanf("%s",n1);
printf("\n\t请再次输入设置的密码:");
scanf("%s",n2);
}
while(k<3)
{
printf("\n");
printf("\n\n\n\t\t\tInput password:");
scanf("%s",a);
k++;
if(strcmp(a,n1)==0)
{printf("\n\t\t\t*欢迎您使用学生成绩管理程序!*\n"); break;}
else if(k<3)
{ printf("对不起,密码错误!请重新输入。"); }
else if(k=3)
{printf("您已经输错三次密码!请重新进入。\n");}
}
这里只给出了一个简单的密码保护模型,当然,也可以在程序中事先设定好一个密码,这样就能有效的防止其他人进入学生成绩管理系统。
程序测试
1.测试系统能否正确显示菜单选项


2.测试系统能否正确增加显示学生信息

输入完成后,显示学生信息

3.测试查询学生信息

4、修改学生信息测试

5.测试删除学生信息:

6、测试排序输出:

下图是删除第 2 名(即学号为 1 的同学)后的降序排序:

程序设计过程中遇到的问题及解决过程
1、在设置密码保护时,出现了错误,当输入两次不同的设置密码时,程序不会提示错误,后来用了一个 while 语句解决了这个问题。
2.在没有输入任何信息的情况下,去执行排序功能,最后显示有一个记录,学号、姓名为空白,成绩都为 0,名次为 1。
3.再输入性别时候,只要不输入 0,程序就会默认为"男",有些地方也有类似的问题,但是建议不要乱输字符。
4.在找错时,发现有些字母、符号竟然打错,所以在编写程序的时候一定要仔细!
5.还发现一些不能找到函数的错误,那是因为没有先定义,一定要"先定以后使用"
课程设计心得及体会
通过此次 C 语言程序设计实践,经过一个多星期的课程设计,感觉自己收获不少在做课程设计的过程中,发现了平时很多没有注意到的问题,例如:返回值函数和不返回值函数两者在主函数中的调用是不同的............
在一些同学的帮助下和在上网查看了大量的资料之后才做出来!这次设计,让我重新掌握了 C 语言,而且还得到了一些用 C 语言解决实际问题的宝贵经验!
更重要的是,这次课程设计虽然花了我不少时间,但正是这些时间,让我见识到了 C 语言的重要性。从这里我也得到一个体会,做一个程序,或者开发一个软件,应该着重从它的后台制作入手,不能做出一个中看不中用的程序或者软件。
相信这次的课程设计为我以后继续从事计算机工作打了一个小小的开头
参考文献
- 刘振安等 《C 程序设计课程设计》 机械工业出版社 2007
- 谭浩强 《C 程序设计教程》 清华大学出版社 2008