C语言编写方案学生成绩管理系统.docx
- 文档编号:12697867
- 上传时间:2023-06-07
- 格式:DOCX
- 页数:34
- 大小:192.91KB
C语言编写方案学生成绩管理系统.docx
《C语言编写方案学生成绩管理系统.docx》由会员分享,可在线阅读,更多相关《C语言编写方案学生成绩管理系统.docx(34页珍藏版)》请在冰点文库上搜索。
C语言编写方案学生成绩管理系统
难易程度
中等
开发语言
C
开发工具
操作系统:
或更高
开发平台:
6.0
关键字
学生成绩管理
《C语言程序设计》课程综合案例
——案例03学生成绩管理系统
3.1需求分析
在对学生成绩管理系统进行需求分析的过程中,需要确定系统的主要功能,对软件开发的主要目的、软件的使用领域和有关该软件开发的软硬件环境进行详细的分析。
3.1.1系统概述
学生成绩管理系统主要用于对学生的学号、姓名及各项学科成绩进行增、删、改、查等操作。
系统给用户提供了一个简单的人机界面,使用户可以根据提示输入操作项,调用系统提供的管理功能。
3.1.2系统运行环境
一、硬件环境
●处理器:
166或更高
●内存:
32
●硬盘空间:
1
●显卡:
显示适配器
二、软件环境
●操作系统:
982000
3.1.3功能需求描述
1.输入学生信息:
用户根据提示输入学生的学号、姓名、各科成绩,并由系统计算总分和平均分,并设置名次的初始值为0。
可一次性输入多条学生记录。
2.查找学生信息:
按照学生姓名查找学生信息,如果存在,则提示用户找到并输出查找结果。
3.插入学生信息:
插入在指定学号的记录前,先查找指定学号是否存在,若存在,直接插入在此记录前,若不存在,则插入在所有记录最后。
4.修改学生信息:
提示用户输入要修改的学生学号,查找该学号是否存在,成功则允许修改该学生的姓名、学科成绩等主要内容,并重新计算总分和平均分;失败,显示没找到。
5.删除学生信息:
提示用户输入要删除的学生学号,如在,则删除,若没有,则提示相应信息。
6.保存信息至文件:
将所有的学生成绩信息保存到磁盘文件中,以方便用户管理。
7.读文件:
将磁盘文件中的数据读到内存以供用户进行查询、修改、删除、添加、排序等操作。
8.学生成绩排序:
根据学生成绩的总分进行降序排列,并将排序结果显示给用户。
9.计算学生总分和平均分:
计算每位学生的总分和平均分,并计算所有学生的总分和平均分。
10.文件备份:
将磁盘文件做一个备份文件,以防止数据意外丢失。
3.2总体设计
3.2.1设计思路
程序设计一般由两部分组成:
算法和数据结构,合理地选择和实现一个数据结构和处理这些数据结构具有同样的重要性。
在管理程序中,若使用静态数组保存数据,则会占用连续的存储空间。
它的缺点是需要预先估计记录大小,如果估计得过大,则浪费空间,如果小了,不容易扩充。
特别是当需要动态变化时,例如插入数据和删除数据等操作需要移动数据,容易出错。
所以我们使用单链表结构来管理学生成绩,这样,不用事先估计学生人数,方便随时插入和删除学生记录,且不必移动数据,实现动态管理。
代价是牺牲一部分空间用来存放表示结点关系的指针。
当然,链表的灵活性也带来了管理的复杂性。
3.2.2系统模块结构图
本程序利用单链表存储结构完成对学生成绩的动态管理,其基本功能模块如图3-1所示。
3.2.3数据结构设计
将一个学生当作一个结点,这个结点的类型为结构体,结构体中的域表示学生的属性,每个结点除了存放属性外,还存放结点之间的关系,即存放指向后继结点的指针。
结点结构如下:
N3定义课程门数,可以根据情况设定
定义数据结构
{
[10];学号
[20];姓名
[N];各门课成绩
;总分
平均分
名次
*指向后继结点的指针
}结构体类型名
3.2.4功能模块设计
一、()主函数
程序采用模块化设计,主函数是程序的入口,主函数不宜复杂,功能尽量在各模块中实现。
()函数执行流程图如图3-2所示。
首先声明一些必要的变量,然后作一无限循环程序,循环体为一个开关语句,该语句的条件值是通过调用主菜单函数得到的返回值,根据该值,调用相应的各功能函数,同时设置一个断点,即当返回值为一定条件时运行()函数结束程序,以免造成死循环。
二、()主菜单
直接利用输出函数输出字符串,在屏幕上显示一个菜单,并显示一个提示输入选项,输入0-12之间的数字,将此数字作为菜单函数的返回值返回主函数,主函数根据这个数字调用相应的功能函数。
制作简便,操作简单,界面如图3-3所示。
图3-3主菜单界面
三、输入记录模块
1.从键盘输入
输入学生信息的同时,创建链表。
按照提示信息输入学号、姓名、三门课程成绩,每输入一个数就按一下回车键,当输入学号首字符为@时结束输入,返回主函数,单链表创建完毕。
在生成链表时,每次新输入的结点放在表头,这样最先输入的结点存放在最后。
对于数据库管理,为避免数据出错或减少数据出错的概率,应考虑数据完整性的验证。
该功能由两个函数()和()完成。
设置头指针为空,申请内存空间,如果申请不到,则内存空间满,无法保存数据,则返回主程序;否则输入数据,并进行相应的校验(学号和姓名调用函数输入和校验),成绩就在()中边输入边验证,以保证输入合法数据。
当成绩输入后,计算该生的总分和平均分,并将名次数据先置0,待排序后再赋予新值。
数据输入后,将其后继结点指针指向当前头结点,新头指针指向新输入结点,这样新插入结点总在头。
数据输入结束后返回链表的头指针到主函数。
2.从文件读入
按照文件的读写要求,先定义一个指向文件的指针,输入读入数据的磁盘文件名,然后确定文件的打开方式。
如果文件打不开,则退出函数,否则选择一种读文件方式,从文件头开始,将记录读入内存,直到文件尾。
文件打开方式和读入方式的确定要依据输出文件的打开方式和写入方式,以免数据读入错误。
如果输出文件是二进制文件,块写操作,读入也应设置为二进制打开方式,块读取方式。
每读入一条记录,都要做好指针链接关系,本模块将新结点链接到当前链表的尾部,链表的顺序和文件保存的顺序一致。
四、更新记录模块
1.查询记录
按照姓名查找结点,从头结点开始顺序查找,成功显示记录信息,失败,显示没找到。
姓名是字符串,比较功能利用字符串比较函数()实现。
2.修改记录
输入要进行修改的学生学号,从头结点开始顺序查找该学号是否存在,成功则允许修改该学生的姓名、学科成绩等主要内容,并重新计算总分和平均分;失败,显示没找到。
3.删除记录
删除指定学号的学生记录。
首先输入要删除结点的学号,输入后根据学号顺序查找结点,如果没找到,则输出没找到信息;;否则,显示找到的结点信息,按任意键后显示已删除信息。
注意删除结点时的操作,如果该结点是首结点,则要修改头指针,如图3-4所示;否则,将该结点的前趋指针的后继指向其后继结点,如图3-5所示,然后释放该结点。
4.插入记录
插入结点需要输入插入位置和新结点信息。
输入某个结点的学号,新结点将插入在这个指定结点之前。
申请空间得到指针,输入新结点信息,存放到新申请的空间中。
设链表头指针为h,p为指定结点的指针,q为p的前趋指针。
从头结点开始循环移动指针p查找指定结点,查找和插入时分以下几种情况处理:
指针p为空,如果p等于头指针h,说明链表为空,则新结点即为头结点,修改指针。
否则,说明表中没有指定结点,则新结点插入在表尾部,此时q所指结点是最后一个结点,所以修改指针>,如图3-6所示。
指针p不为空,如果p等于h,说明新结点插入在当前第一个结点之前,为新的头结点,修改指针>,,如图3-7所示。
否则,说明新结点的位置应在p和q两个结点之间,修改指针>,>,如图3-8所示。
五、统计纪录模块
1.学生成绩计算
从头指针开始,每读一条记录,将该生的总分累加,并统计记录条数,当所有数据处理完毕,求出平均分,最后输出结果为所有学生的总分和平均分。
2.学生成绩排序
对于学生成绩管理,一个很重要的运算是将学生按照分数由高到低排名,本模块实现按照总分排序功能。
排序算法有很多,对于确定的数据结构,应选用一种合适的算法。
由于学生信息采用的是单链表存储结构,所以选用直接插入算法较为简单。
直接插入算法的基本方法是:
每步将一个待排序的记录按其排序码值的大小插到前面已经排序好的表中,直到全部插入为止。
基于这样的方法首先将链表的头结点看作是已排好序的结点,然后取下一个结点作为待排序的结点,插入到已排好序的表中。
由于单链表的特性,所以具体的思路如下:
;
先将原表头结点作为新排好序表的头结点h,原表下一个结点作为原表头结点h1,设原表如图3-9所示,表中只列出总分数据。
原表头结点为待排序结点,将其总分与新表结点的总分进行比较,如果待排序结点总分大,则插在新表的头,否则插入在其后,原表头结点后移一位,如图3-10所示。
重复第二步,则将原表头结点的总分和新表结点的总分进行比较,如果待排序结点总分小,则移动新表指针,直到找到合适的位置将其插入,直到原表为空,所有结点排序完毕,如图3-11所示。
六、输出记录模块
1.文件备份模块
为了保存数据,防止意外发生,为数据做备份是很有必要的。
本模块是将文件读写功能结合到一起的应用。
先输入源文件名,再输入目标文件名,然后利用文件读写函数将源文件中的信息写到目标文件中。
2.学生信息保存至文件
将学生信息保存到指定文件中。
按照文件的读写要求,先定义一个指向文件的指针,输入要保存的磁盘文件名,如果输入的是绝对路径,则文件保存到指定位置;如果只给文件名,则文件保存在6.0默认的路径下。
然后确定文件的打开方式,打开文件。
如果文件打不开,则退出程序,否则选择一种写文件方式,从链表的头指针开始,顺序将记录写入文件,直到所有记录写完,标志就是移动后指针为空。
3.显示所有学生信息输出至屏幕
学生成绩表建立好后,更频繁的操作是显示和查找记录,本模块实现显示所有链表数据功能。
输出界面如图3-12所示。
图3-12输出界面
由于单链表只能采取顺序访问的方法,所以定义一个指向结点的临时变量p,初值为单链表的头指针,输出指针所指记录的数据后,将指针后移一个记录,直到p指针值为空,则所有记录输出完毕。
设计本模块时注意输出格式以二维表格的形式输出,直观漂亮。
输出的第一列为记录号。
注意调整格式,对齐表格线。
3.3详细设计
3.3.1程序预处理
包括加载头文件,定义结构体、常量和变量,并对它们进行初始化。
""函数
""标准库函数
""字符串函数
""字符操作函数
""控制台输入输出函数
""动态地址分配函数
""内存操作函数
N3定义课程门数,可以根据情况设定
定义数据结构
{
[10];学号
[20];姓名
[N];各门课成绩
;总分
平均分
名次
*指向后继结点的指针
}结构体类型名
/**********以下是函数原型***********/
*();初始化函数
*();创建链表
(*h);显示所有记录
(*h)查找记录
*(*h);插入记录
*(*h);修改记录
*(*h);删除记录
(*h);记录保存为文件
*();从文件中读记录
(*h);计算总分和平均分
*(*h)排序
()文件备份
(**);输入字符串,并进行长度验证
();主菜单函数
3.3.2主函数()
实现对整个程序的运行控制,以及相关功能模块的调用。
()
{
*;链表定义头指针
()初始化链表
("");清屏
(;;)无限循环
{
(())
{
0();执行初始化
1();输入记录创建链表
2();显示所有记录
3()查找记录
4()插入记录
5()修改记录
6:
()删除记录
7()保存文件
8()读文件
9()计算总分和平均分
10()排序
11()文件备份
12(0)结束程序
}
}
0;
}
3.3.3()主菜单
用户进入通讯录管理系统时,需要显示主菜单,提示用户进行选择,完成相应任务。
此代码被()函数调用。
/********************************************
函数功能:
显示主菜单,进行功能选择
入口参数:
无
出口:
返回用户的选项
调用方式:
()
********************************************/
()
{
s[80];
c;
("按任意键继续\n");
();
("")清屏
("*************学生成绩管理系统菜单***************\n\n");
("0.初始化\n");
("1.输入记录\n");
("2.显示全部记录\n");
("3.查找记录\n");
("4.插入记录\n");
("5.修改记录\n");
("6.删除记录\n");
("7.保存文件\n");
("8.读文件\n");
("9.计算总分和平均分\n");
("10.按总分排序\n");
("11.文件备份\n");
("12.退出\n");
("*****************************************\n");
{
("\n输入你的选择(0-12):
");
("");
(s)将数字字符串转换为数值
}(c<0>12);
c;
}
3.3.4初始化
/********************************************
函数功能:
初始化链表
入口参数:
无
出口:
返回一个链表空指针
调用方式:
()
********************************************/
*()
{
;
}
3.3.5输入记录模块
一、从键盘输入
按照提示信息输入学号、姓名、三门课程成绩,并计算出总分和平均分,同时,创建链表。
/*******************************************************
函数功能:
输入字符串,并进行长度验证
入口参数:
:
提示信息,s:
待验证字符串,:
长度
出口:
无
调用方式:
(“输入姓名:
”>,20);
*******************************************************/
(**)
{
p[255];;
{
()显示提示信息
(“”)输入字符串
((p)>)(“\!
\n”)进行长度验证,超过值重新输入
}((p)>);;
()将输入的字符串拷贝到字符串s中
}
/**********************
函数功能:
创建链表
入口参数:
无
出口:
返回链表头指针
调用方式:
();
**********************/
*()
{
i;s;
*,*;
(;;)
{
(*)(())申请空间
()若指针为空
{
(“\n”)提示内存溢出
;返回空指针
}
(“输入学号:
”>,10)输入学号并检验
(>[0]’@’)如果学号首字符为@,结束输入
(“输入姓名:
”>,20);输入姓名并检验
(“请输入门课程成绩\n”)提示开始输入成绩
0计算每个学生的总分,初值为0
(0<)
{
{
(“课程:
”1)提示输入第几门课程
(“”>[i])输入成绩
(>[i]>100>[i]<0)
(“成绩超出指定范围!
”);
}(>[i]>100>[i]<0);
>[i]累加各门成绩
}
>将总分保存
>求平均分
>0未排序前此值为0
>将头结点作为新输入结点的后继结点
新输入结点为新的头结点
}
返回头指针
}
二、从文件读入数据
/*******************************************************
函数功能:
从文件读数据,并把读入的数据链入链表
入口参数:
无
出口:
返回链表头指针
调用方式:
();
*******************************************************/
*()
{
*p,*q,*;
*;
[50];
("请输入文件名,例如:
c:
\\f1\\:
\n")提示文件名格式信息
("");
(((,"")))
{
("不能打开文件!
\n");
(1);
}
("\n读文件\n");
(*)(());
()
{
("内存溢出!
\n");
h;
}
;
(())
{
(1((),1))
;
>(*)(());
(>)
{
("内存溢出!
\n");
h;
}
;
>;
}
>;;
();
("成功读取文件!
\n");
h;
}
3.3.6更新记录模块
一、查找记录
从头结点开始顺序查找,查找指定姓名的记录。
/******************************
函数功能:
按照姓名查找记录
入口参数:
h:
链表头指针
出口:
无
调用方式:
();
******************************/
(*h)
{
*移动指针
s[20]存放姓名的字符数组
("")清屏
("请输入要查找的姓名:
\n");
("")输入姓名
;
((>))
>移动指针,指向下一结点
()
("没有姓名为的学生!
\n");
{
("\n\n\n**********************查找结果******************\n");
("学号\t\t姓名\t课程1\t课程2\t课程3\t总分\t平均分\t名次\n");
("\n");
("\\.1f\.1f\.1f\.1f\.1f\\n">,
>>[0]>[1]>[2]>>>);
("\n");
}
}
二、插入记录
在指定学号的学生前插入一条记录。
若指定学号不存在且学生表为空表,则直接插入此学生信息为头结点,若学生表不为空表,则在表尾插入。
若指定学号存在,且为头结点,则新输入的学生信息作为新的头结点插入在指定学号前,否则,作为中间结点直接插入到指定学号前。
/******************************
函数功能:
插入记录
入口参数:
h:
链表头指针
出口:
返回链表头指针
调用方式:
();
******************************/
*(*h)
{
*p,*q,*指向插入位置,q是其前趋,指新插入记录
s[10]保存插入点位置的学号
s1i;
("在哪个学号前插入?
");;
("")输入插入点学号
("\n请输入新的记录:
\n");
(*)(())申请空间
()
{
("\n")提示内存溢出
;返回空指针
}
("输入学号:
">,10)输入学号并检验
("输入姓名:
">,20);输入姓名并检验
("请输入门课程成绩\n")提示开始输入成绩
s1=0计算每个学生的总分,初值为0
(0<)
{
{
("课程:
"1)提示输入第几门课程
("">[i])输入成绩
(>[i]>100>[i]<0)
("成绩超出指定范围!
");
}(>[i]>100>[i]<0);
s1>[i]累加各门成绩
}
>1将总分保存
>1求平均分
>0名次赋为0
>设后继指针为空
;
;
((>))查找插入位置
{
;
>;
}
()如果p指针为空,说明没有指定结点
()同时p等于h,说明链表为空
新记录则为头结点
>不为空,但p不等于h,将新结点插在表尾
()
{
>如果p等于h,则新结点插入在第一个结点之前
新结点为头结点
}
{
>不是头结点,则是中间某个位置,新结点的后继为p
>新结点作为q的后继结点
}
("成功插入!
");
h;
}
三、修改记录
/********************************
函数功能:
修改指定学号的学生信息
入口参数:
h:
链表头指针
出口:
返回链表头指针
调用方式:
();
********************************/
*(*h)
{
*为查找到要修改的结点指针
s[10]存放学号
s1;
("")清屏
("请输入要修改的学生学号:
");
("");
;
((>))查找
{
>;
}
()
("没有该学生!
\n");
{
("找到该学生!
学生信息见下列\n");
("学号\t\t姓名\t课程1\t课程2\t课程3\t总分\t平均分\t名次\n");
("\n");
("\\.1f\.1f\.1f\.1f\.1f\\n">>,
>[0]>[1]>[2]>>>);
("\n");
("请输入修改信息:
\n");
("输入学号:
">,10)输入学号并检验
("输入姓名:
">,20);输入姓名并检验
("请输入门课程成绩\n")提示开始输入成绩
s1=0计算每个学生的总分,初值为0
(0<)
{
{
("课程:
"1)提示输入第几门课程
("">[i])输入成绩
(>[i]>100>[i]<0)
("成绩超出指定范围!
");
}(>[i]>100>[i]<0);
s1>[i]累加各门成绩
}
>1将总分保存
>1求平均分
("修改成功!
\n");
}
h;
}
四、删除记录
/********************************
函数功能:
删除指定学号的记录
入口参数:
h:
链表头指针
出口:
返回链表头指针
调用方式:
();
********************************/
*(*h)
{
*p,*为查找到要删除的结点指针为其前趋指针
s[10]存放学号
;
("")清屏
("请输入要删除的学生学号:
");
("");
;
((>))查找
{
;
>;
}
()
("没有该学生!
\n");
{
("找到该学生!
学生信息见下列\n");
("学号\t\t姓名\t课程1\t课程2\t课程3\t总分\t平均分\t名次\n");
("\n");
("\\.1f\.1f\.1f\.1f\.1f\\n">>,
>[0]>[1]>[2]>>>);
("\n");
("确定要删除这条记录吗?
():
\n");
()此处一定要用函数输入,其它函数均不可以
('Y''y')
{
()若被删结点是头结点
>修改头指针指向下一条记录
>>不是头结点,将p的后继结点作为q的后继结点
(p);
("删除成功!
\n");
}
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 语言 编写 方案 学生 成绩管理系统