学生成绩管理系统C++.docx
《学生成绩管理系统C++.docx》由会员分享,可在线阅读,更多相关《学生成绩管理系统C++.docx(15页珍藏版)》请在冰豆网上搜索。
学生成绩管理系统C++
《学生成绩管理系统》的设计与实现
一、概述:
1、每一条记录包括一个学生的学号、姓名、3门成绩、平均成绩。
25175.
2、输入功能:
可以一次完成无数条记录的输入。
3、显示功能:
完成全部学生记录的显示。
4、查找功能:
完成按姓名查找学生记录,并显示。
5、排序功能:
按学生平均成绩进行排序。
6、插入功能:
按平均成绩高低插入一条学生记录。
7、保存功能:
将学生记录保存在任何自定义的文件中,如保存在:
c:
\。
8、读取功能:
将保存在文件中的学生记录读取出来。
9、有一个清晰美观界面来调用各个功能
二、要求
1、整个系统均用C语言实现;
2、利用指针、链表来实现学生成绩的数据结构设计;
3、系统具有输入、显示、查询、删除、排序、插入,保存、读取基本功能;
4、系统的各个功能模块都用函数的形式来实现;
5、可以将学生成绩信息保存在文件中。
6、可以将学生信息从文件中读取出来。
三、内容
整个系统除了主函数外,另外还有10个函数,实现八大功能:
输入功能、显示功能、查找功能、排序功能、插入功能、保存功能、读取功能。
各个函数的详细设计说明分别如下:
1、 主函数()
利用无限次循环(;;)和()实现各函数的调用,系统根据输入的数字选项来调用相应的函数。
2、 初始化函数 *()
这是一个无参函数,里面只有一个语句,它的作用是使链表初始化,使的值为。
比如:
没有这个函数的话,在你没有输入任何数据的情况下,去执行显示功能的时候会显示一些乱码!
3、 菜单选择函数();
这是一个无参函数,主要实现“功能选择”的界面,在这个界面里有显示系统的九大功能,根据每个功能前面的序号进行选择,中间还显示系统当前的时间。
等执行完每一个函数功能后,按任一键回到主界面也要通过这个函数来实现!
4、 输入记录函数*()
这是一个无参函数,用来执行第学生成绩记录的输入,当学生为0时停止输入,函数结束后,带回一个指向链表头的指针。
算法:
先声明一个首节点,并将>设为。
每输入一个数据就声明一个新节点p,把>设为,并且链接到之前列表的尾端。
5、 显示记录函数(*)
这是一个不返回值的有参函数,形参为“链表头的指针”,负责对全部学生成绩记录的输出,不足之处就是不能对学生成绩进行分页显示。
算法:
先将p结点的指针指向第一个结点,将p结点(即第一个结点)的数据输出。
然后再将p结点的指针指向p指针的的指针(即下一结点),将p结点(即第一结点)的数据输出。
重复执行此步聚直到p指针指向为止。
6、 查找记录函数(*)
这是一个不返回值的有参函数,形参为“链表头的指针”,实现按学号对某个学生进行查找,并显示所查找到的记录。
算法:
采用线性查找法往下一个节点查找。
输入所要查找的学生的学号s,设一个指针变量p,先指向第一个结点,当(>)p时,使p后移一个结点,如果,输出p所指的结点
7、 删除记录函数*(*)25175.
这是一个有参函数,形参为“链表头的指针”,先输入要删除的学生记录的学号,找到后显示该学生信息,等确认后便可按“Y”进行删除。
算法:
从p指向的第一个结点开始,检查该结点中的值是否等于输入的要求删除的那个学号。
如果相等就将该结点删除,如不相等,就将p后移一个结点,再如此进行下去,直到遇到表尾为止。
8、排序函数*(*)
这是一个有参函数,形参为“链表头的指针”,按学生成绩的平均分高低进行排序,还可以显示名次。
9、 插入函数*(**)
这是一个有参函数,形参有两个,一个是“链表头的指针”,一个是“待插入指针”,按照原来成绩平均分的高低进行插入,插入后会重新进行排序,并返回。
算法:
先将学生的成绩按平均分由高分到低分进行排序,再插入一个新生的结点,要求按平均分的高低顺序插入。
先用指针变量p0指向待插入的结点,p1指向第一个结点。
如果p0->,则待插入的结点不应插在p1所指的结点之前。
此时将p1后移,并使p2指向刚才p1所指的结点。
重复以上的步骤,直到p0->>1->为止。
这时将p0指向的结点插到p1所指结点之前。
但是如果p1所指的已是表尾结点,则p1就不应后移了。
如果p0->比所有结点的都小,则应将p0所指的结点插到链表末尾。
如果插入的位置既不在第一个结点之前,又不在表尾结点之后,则将p0的值赋给p2->,使p2->指向待插入的结点,然后将p1的值赋给p0->,使得p0->指向p1指向的变量。
如果插入位置为第一个结点之前,则将p0赋给,将p1赋给p0->。
如果要插到表尾之后,应将p0赋给p1->,赋给p0->。
最后再调用排序的函数,将学生成绩重新排序.
10、保存数据到文件函数(*)
这是一个不返回值的有参函数,形参为“链表头的指针”,可以把学生记录保存在电脑上由自己任意命名的二进制文件。
11、从文件读数据函数*()
这是一个不返回值的有参函数,形参为“链表头的指针”,根据输入的文件地址进行读取。
四、调试分析
(1)刚开始没有那个初始化函数,程序运行后,没有输入任何数据就试得去执行显示功能,结果显示的是一些乱码!
加入初始化函数后,这种现象也随之消失。
(2)刚开始执行输入函数,按学号顺序输入十个学生的成绩,输完后执行显示功能,学生成绩记录是按学号的反顺序显示的,试着在其中增加一些语句,希望能把学号按正常顺序显示,但暂时没有成功,所以在输入成绩时只能按学号反顺序输入,最后就按学号正常顺序输出了。
(3)刚开始时,先把成绩按平均分排序,再插入一个学生的成绩,执行显示功能,虽然插入的学生的成绩能正常插入,但该学生的名次为0。
后来,在插入成绩之后,调用排序函数,把所有成绩重新排序一次。
(4)在输入函数中设了一个无限循环,可以输入无数个学生的成绩信息,当学号为0的时候则停止输入。
(5)输入太多个学生的成绩时,屏幕显示不能控制为一页一页显示,所以为了方便起见,不要输入太多记录,十七左右为最佳。
(6)在没有输入任何信息的情况下,去执行排序功能,最后显示有一个记录,学号、姓名为空白,成绩都为0,名次为1。
(7)在输入选项时不能输入字母,否则会死循环,建议不要乱输字母。
五、总结
经过一个多星期的C语言课程设计,感觉自己收获不少!
首先是:
链表本来上课是没有上的,但这个课程设计里面主要都是用链表,因为要达到这样的功能,使用链表相当方便,但不容易理解,所以在这方面我很了很多的时间看课本和参考课外书,使C语言的知识强化了不少。
其次,在做课程设计的过程中,发现了平时很多没有注意到的问题,例如:
返回值函数和不返回值函数两者在主函数中的调用是不同的…………
更重要的是,这次课程设计虽然花了我不少时间,但正是这些时间,让我见识到了C语言的重要性。
这个学生成绩管理系统都是在自己知识范围内完成的,所以界面清晰简单,可能不是很好看,但绝对实用!
从这里我也得到一个体会,做一个程序,或者开发一个软件,应该着重从它的后台制作入手,不能做出一个中看不中用的程序或者软件。
相信这次的课程设计为我以后继续从事计算机工作打了一个小小的开头。
由于这是第一次进行设计,写文档,难免会写得不好!
学生成绩管理系统
/*头文件*/
<>
<>
<> /*其它说明*25175.
<> /*字符串函数*/
<> /*内存操作函数*/
<> /*字符操作函数*/
<> /*动态地址分配函数*/
()
/*定义结构体数组用于缓存数据*/
{[6];
[5];
[3];
;
;
;
*;
};
/*函数原型*/
*(); /*初始化函数25175*/
(); /*菜单函数*/
*(); /*创建链表*/
(*); /*显示全部记录*/
(*); /*查找记录*/
*(*); /*删除记录*/
*(*); /*排序*/
*(**); /*插入记录*/
(*); /*保存文件*/
*(); /*读文件*/
/*主函数界面*/
()
{*;
(); /*链表初始化,使的值为*/
(;;) /*循环无限次*/
{(())
{
1();
2();
3();
4();
5();
6(); /*表示返回地址*/
7();
8();;
9(0); /*如菜单返回值为9则程序结束*/
}
}
}
/*初始化函数*/
*()
{
; /*返回空指针*/
}
/*菜单选择函数*/
()
{n;
d; /*定义时间结构体*/
(); /*读取系统日期并把它放到结构体d中*/
("......"); /*按任一键进入主菜单*/
(); /*从键盘读取一个字符,但不显示于屏幕*/
(); /*清屏*/
("********************************************************************************\n");
("\t\t \n");
("\n\t\t \n");
("****************************************************************************\n");
("\t\t\t1.\n"); /*输入学生成绩记录*/
("\t\t\t2.\n"); /*显示*/
("\t\t\t3.\n"); /*寻找*/
("\t\t\t4.a\n"); /*删除*/
("\t\t\t5.a\n"); /*排序*/
("\t\t\t6.\n"); /*插入*/
("\t\t\t7.\n"); /*保存*/
("\t\t\t8.\n"); /*读取*/
("\t\t\t9.\n"); /*退出*/
("\n\t\t .\n");
("********************************************************************************\n");
("\t\t\t\\\\\\n"); /*显示当前系统日期*/
{
("\n\t\t\(1~9):
");
("");
}(n<1>9); /*如果选择项不在1~9之间则重输*/
(n); /*返回选择项,主函数根据该数调用相应的函数*/
}
/*输入函数*/
*()
{;
*,*p; /*定义函数.此函数带回一个指向链表头的指针*/
();
(;;)
{(*)(); /*开辟一个新的单元*/
() /*如果指针p为空*/
{("\."); /*输出内存溢出*/
(); /*返回头指针,下同*/
}
("(0):
");
("">);
(>[0]'0'); /*如果学号首字符为0则结束输入*/
(":
");
("">);
("\n",3); /*提示开始输入成绩*/
0; /*计算每个学生的总分,初值为0*/
(0<3) /*3门课程循环3次*/
{
{
(":
"1);
("">[i]);
(>[i]<0>[i]>100) /*确保成绩在0~100之间*/
(".\n");
}(>[i]<0>[i]>100);
>[i]; /*累加各门成绩*/
}
>; /*将总分保存*/
>()3; /*先用强制类型转换将s转换成型,再求平均值*/
>0; /*未排序前此值为0*/
>; /*将头结点做为新输入结点的后继结点*/
; /*新输入结点为新的头结点*/
}
();
}
/*显示全部记录函数*/
(*)
{0; /*统计记录条数*/
*p; /*移动指针*/
();
; /*初值为头指针*/
("\n************************************************************************\n");
("\n");
("|| | | 1 | 2 | 3 | | ||\n");
("\n");
()
{
;
("|%3d| %4s | 4s | %3d | %3d | %3d | %3d | %4.2f | 5\n",
i,>>>[0]>[1]>[2]>>>);
>;
}
("\n");
("****************************************************************************\n");
}
/*查找记录函数*/
(*)
{*p; /* 移动指针*/
s[5]; /*存放姓名用的字符数组*/
();
(".\n");
("");
; /*将头指针赋给p*/
((>)p) /*当记录的姓名不是要找的,或指针不为空时*/
>; /*移动指针,指向下一结点*/
() /*如果指针不为空*/
{("\n*************************************************************************\n");
("\n");
("| | | 1 | 2 | 3 | | ||\n");
("\n");
("| %4s | %4s | %3d | %3d | %3d | %3d | %4.2f | 5\n",
>>>[0]>[1]>[2]>>>);
("\n");
("*****************************************************************************\n");
}
("\.\n"); /*显示没有该学生*/
}
/*删除记录函数*/
*(*)
{n;
*p1,*p2; /*p1为查找到要删除的结点指针,p2为其前驱指针*/
[6]; /*s[6]用来存放学号用来输入字母*/
();
(":
");
("");
p12; /*给p1和p2赋初值头指针*/
((p1->)p1) /*当记录的学号不是要找的,或指针不为空时*/
{p21; /*将p1指针值赋给p2作为p1的前驱指针*/
p11->; /*将p1指针指向下一条记录*/
}
((p1->)0) /*学号找到了*/
{("**************************************************************************\n");
("\n");
("| | | 1 | 2 | 3 | | ||\n");
("\n");
("| %4s | %4s | %3d | %3d | %3d | %3d | %4.2f | 5\n",
p1->1->1->[0]1->[1]1->[2]1->1->1->);
("\n");
("*****************************************************************************\n");
("?
");/*提示是否要删除,输入Y删除则退出*/
(;;)
{("");
('n''N'); /*如果不删除,则跳出本循环*/
('y''Y')
{
(p1) /*若p1,说明被删结点是首结点*/
1->; /*把第二个结点地址赋予*/
p2->1->; /*否则将一下结点地址赋给前一结点地址*/
1;
("\.\n");
("'t.\n"); /*删除后就跳出循环*/
}
}
}
("\.\n"); /*找不到该结点*/
();
}
/*排序函数*/
*(*)
{0; /*保存名次*/
*p1,*p2,*t,*; /*定义临时指针*/
>; /*将原表的头指针所指的下一个结点作头指针*/
>; /*第一个结点为新表的头结点*/
() /*当原表不为空时,进行排序*/
{
; /*取原表的头结点*/
>; /*原表头结点指针后移*/
p1; /*设定移动指针p1,从头指针开始*/
p2; /*设定移动指针p2做为p1的前驱,初值为头指针*/
(>1) /*作成绩平均分比较*/
{
p21; /*待排序点值小,则新表指针后移*/
p11->;
}
(p12) /*p12,说明待排序点值大,应排在首位*/
{
>1; /*待排序点的后继为p*/
; /*新头结点为待排序点*/
}
/*待排序点应插入在中间某个位置p2和p1之间,如p为空则是尾部*/
{
>1; /*t的后继是p1*/
p2->; /*p2的后继是t*/
}
}
p1; /*已排好序的头指针赋给p1,准备填写名次*/
(p1) /*当p1不为空时,进行下列操作*/
{
; /*结点序号*/
p1->; /*将结点序号赋值给名次*/
p11->; /*指针后移*/
}
(".\n"); /*排序成功*/
();
}
/*插入记录函数*/
*(**)
{*p0,*p1,*p2;
1;
p1; /*使p1指向第一个结点*/
p0; /*p0指向要插入的结点*/
("\a.\n"); /*提示输入记录信息*/
(":
");
("">);
(":
");
("">);
(".\n",3);
1=0; /*保存新记录的总分,初值为0*/
(0<3)
{
{
(":
"1);
("">[i]);
(>[i]>100>[i]<0)
(".\n");
}(>[i]>100>[i]<0);
11>[i]; /*累加各门成绩*/
}
>1; /*将总分存入新记录中*/
>()1/3;
>0;
() /*原来的链表是空表*/
{00->;} /*使p0指向的结点作为头结点*/
{((p0->)(p1->))
{p21; /*使p2指向刚才p1指向的结点*/
p11->; /*p1后移一个结点*/
}
(p0->>1->)
{
(1)0; /*插到原来第一个结点之前*/
p2->0; /*插到p2指向的结点之后*/
p0->1;}
{p1->00->;}/*插到最后的结点之后*/
}
1;/*结点数加1*/
();