赞
踩
C语言课程设计报告
源码下载方式
关注微信公众号 跨时代的jay
回复 学生成绩管理系统
为大家提供一些帮助!
获取链接后复制到浏览器即可下载
课题题目: 学生信息管理系统
班 级: 信卓11801
姓 名: 聂健
班级序号: 09
同组成员: 无
完成时间: 2019 年 12 月 11 日
目录
一.题目
二.设计目的
三.总体设计
四.详细设计
五.调试与测试:
六.课程设计心得及体会
七.程序清单
一.题目:学生信息管理系统
要求:从文件中读取原始数据,并将修改后的数据保存在一个新的文件当中。
功能:浏览所有学生的所有信息
用姓名和学号查询学生的信息
用姓名和学号修改学生的信息
用姓名和学号删除学生
统计各个课程分数段的人数
统计总分和各个课程的最高分、最低分以及对应的姓名
二.设计目的
如今学校的学生越来越多,成绩管理的工作量越来越大,手工管理成绩的弊端也越来越明显。随着科学技术的不断提高,计算机科学日渐成熟,它已进入人类社会的各个领域并发挥着越来越重要的作用。作为计算机应用的一部分,使用计算机对学生档案信息进行管理,具有手工管理所无法比拟的优点。所以我想借本次课程设计之际,设计一个简易的学生成绩管理系统。
掌握: 1.掌握动态创建链表,并实现对数据的删除,检索,修改。增强工程化意识,提高c语言实践能力。
三.总体设计
(1)程序源文件分为:
1.student.h 包含所有的头文件以及定义
2.function.cpp 实现各个函数的功能
3.main.cpp 主函数
4.data.txt 学生原始数据
(2)主函数实现菜单的选择:使用swicth语句实现菜单的选择
1.浏览学生信息
2.查询学生信息
3.修改学生信息
4.删除学生信息
5.各科成绩
6.最高分最低分以及对应的姓名
(3)函数包括:
1.struct student * create() //用动态链表建立基础的学生信息库 从文件中将学生信息读取出来
2.void sort(struct student *head) //排序
3.void locatename(struct student *head) //通过姓名查询信息
4.void locatenum(struct student *head) //通过学号查询信息
5.struct student * delname(struct student *head) //通过姓名删除学生信息
6.struct student * delnum(struct student *head) //通过学号删除学生信息
7.void changename(struct student *head) //通过姓名去修改学生数据
8.void changenum(struct student *head) //通过学号去修改学生数据
9.void filein(struct student *head) //保存到文件中
10.void print(struct student *head) //打印所有学生信息
11.void ABCD(struct student *head) //统计各分段的人数
12.void max(struct student * head) //总分以及各个课程的最高分,最低分以及对应的姓名
对于创建链表和删除学生这两个函数需要返回head
创建链表时返回head:
其他函数中都传入了一个参数head
那么都可以访问到链表中的所有数据
删除学生返回head:
当删除第一个学生时,即把头给删了
这时需要换头 head = delname(head); head= delnum(head);
其它函数使用void类型即可
四.详细设计
使用结构体链表实现上述要求,在头文件中定义结构体,分为数据域和指针域。首先创建一个动态链表,将文件中的原始数据保存在链表中,指针域将链表链接起来。
实现整个系统:菜单调用函数
<0> filein(head); //将修改后的信息保存在新的文件中 data11.txt
<1> print(head); //打印所有学生的所有信息 实现菜单1的功能
<2> locatename(head) //通过姓名查询单个学生的所有信息 实现菜单2的姓名查询功能
locatenum(head) //通过学号查询单个学生的所有信息 实现菜单2的学号查询功能
<3> changename(head); //通过姓名修改学生的信息 实现菜单3的姓名查询功能
changenum(head); //通过学号修改学生的功能 实现菜单3的学号查询功能
<4> head= delname(head); //通过姓名删除学生数据 实现菜单4的姓名删除功能
head= delnum(head); //通过学号删除学生数据 实现菜单4的学号删除功能
//如果删除的是头 这时头换了 p = head; head = p->next;
<5> ABCD(head); //统计各个分数段的人数 并将运行结果写进一个新的文件 abcd.txt
<6> max(head); //输出总分和各个课程的最高分和最低分的相关信息
各个函数的实现过程:
1.动态创建链表
//动态创建链表的过程struct student *p,*q,*head;
p = q = (struct student *)malloc(sizeof(struct student));//开辟空间head = p;
while(p!=NULL)
{
q = (struct student *)malloc(sizeof(struct student));
p->next = q;
p = q;
}
p->next = NULL;return head;//在while中将数据域加入即可
核心部分即为:链表连接过程使用while循环,使用feof判断有没有到达文件的最后一行。
创建链表流程图
对于从文件中读取数据,核心部分是不变的。但是需要注意的是,由于文件中第一行是字符串,所以需要使用fgets读取第一行数据。从第二行开始将数据依次保存在里链表中。
从文件中将数据赋值给变量,使用fscanf。
读取完毕后,fclose关闭文件。
2.排序
为什么要将排序单独写成一个函数?
当老师问我这个问题时,我是这样回答的。因为在后面的功能中有删除以及修改学生的数据,我只要调用一下函数,即可实现排序的实时更新。
使用擂台法进行排序。
3.查询信息通过姓名
通过学号
姓名匹配需要调用一个函数 strcmp(A,B);
当两字符串完全相同时,函数返回0。
当为整形时,只许判断 if(A == B)即可。
(查询学生信息流程图)
4.修改学生信息
对于修改学生数据,与查询是差不多的流程。当匹配到了学生后,重新赋值就可以了。
scanf("%f",&p->s1);
scanf("%f",&p->s2);
scanf("%f",&p->s3);
此时,重新调用一下排序函数,sort(head);即可实现数据的实时更新。
5.删除学生
struct student *p , *q;
p = head;
while( p不匹配 && p->next!=NULL)
{
q = p;
p = p->next;
}//一旦匹配,跳出whileif(匹配)
{
if( p == head ) //如果是头匹配 {
head = p->next;//换头,此过程就把头也删了 }
else
{
q->next = p->next;
}
}if(不匹配)
{
NONE
}
return head;//当删除了头时,把新的头返回
删除学生流程图
6.输出所有学生的所有数据
print(head);
将链表中的头找到,即可找到访问所有人的所有数据
p = head;
while(p)
{
printf( "%ld\t%s\t%.2f\t%.2f\t%.2f\t%.2f\t%3d\n",p->num,p->name , p->s1 , p->s2 , p->s3 , p->sum , p->rank );
p = p->next;
7.统计各分数段的人数
统计各个等级的人数流程图
遍历链表,对数据域进行判断
设置12个变量,初始化为1
将90-100设为等级A,将80-89设置为B,将60-79设置为C将<60设置为D。
每次判断,在相应的位置就+1,最终算出人数,以一个表格的形式展现,并定义文件指针,将结果写进一个新的文件当中。统计总分和各科的最高分,最低分,以及相应的姓名
使用擂台法进行比较
while(p!=NULL)
{
if(p->sum > summax->sum)
{
summax = p;
}
p = p->next;
}
总分与各科的方法是一样的
当找到了这个节点,就可以找到对应的姓名。
五.调试与测试
在这个过程中出现了许许多多的问题,在不断的调试中,将bug不断地修复。开始有删除头删不掉的情况,打印的时候排名有问题,最终形成了第三个版本的此系统。
一般情况下我是首先去测试一下代码,看看所有的功能是否都能正常使用。如果出现逻辑上的问题,会debug寻找错误的原因,并去解决bug。一个常见的方法就是合理的使用printf。
比如之前我就遇到了一个问题。
当时在if语句中是这么写的,if(answer == 1),运行就出问题。我要查询的是姓名查询,但是按了1后没有反应。然而说明在哪里出现了问题。于是我用printf测试。
到底有没有进入到locatename(head)这个函数。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。