C++学生信息管理系统设计报告.docx
《C++学生信息管理系统设计报告.docx》由会员分享,可在线阅读,更多相关《C++学生信息管理系统设计报告.docx(23页珍藏版)》请在冰豆网上搜索。
C++学生信息管理系统设计报告
摘要
这一款学生信息管理小系统采用面向对象的设计方法,主要是面对管理端,管理者可以通过密码登录进入系统对学生的各类数据统进行管理和维护。
在主界面中主要设置了8个基本功能:
增加学生、显示全部学生、计算平均成绩、删除一个学生、按年级输出学生信息、按性别输出学生信息、按姓名检索学生、按总分进行排序。
这些功能基本上能满足学生管理的基本要求,此程序可以初步体现课程设计的目标。
采用VisualC++作为开发工具,界面简单友好,操作方便易行,便于维护,是一个功能比较完善的管理系统。
关键字:
学生系统;继承;重载;派生
1.引言
随着我国经济与计算机技术的日益发展,信息化技术逐渐取代传统人工作业,而学生也不例外。
由于学生信息管理系统应用范围之广,版本各式各样,功能不尽管理系统相同。
如何做出一个比较出众的学生系统,是对程序员的一种考验,这其中选择一种合适的程序设计语言、一个开发平台和编程思想是至关重要的。
而建成一个数字化的学生信息管理系统,进行统一的管理,管理者就会对学生情况得到及时准确的了解,并根据具体情况提供及时的查询与修改。
这样,就可以使学生的管理变得更为高效。
本系统是从学生信息管理系统最基本的功能进行设计和开发。
设计希望用VC++编写一个界面美观流畅学生信息管理系统,管理者能够使用它对学生数据进行基本的查询、增加、删除、修改等,而且程序运行结果正确,操作方便,界面美观,逻辑层次清楚,程序结构合理,程序代码精简易懂。
管理者通过密码登录进入学生信息管理系统,根据需要可以实现以下功能:
增加学生、显示全部学生、计算平均成绩、删除一个学生、按年级输出学生信息、按性别输出学生信息、按姓名检索学生、按总分进行排序。
该学生信息管理系统是采用面向对象的程序设计思想,选择C++语言进行编写的,整个程序由一个学生基类和两个年级派生类、若干个函数及主函数构成的。
使用面向对象的程序设计方法是设计一个复杂的软件系统时,首要的问题是确定该系统是有哪些对象组成的,并且设计这些对象。
本学期,专业开设了C++面向对象课程设计,为我们提供了一个既动手又动脑独立实践的机会,这就要求根据所学的C++程序设计原理与程序设计的知识,能够针对一个小型的学生信息管理系统,进行系统的任务分析,系统设计,运行调试等,完成题目要求的功能。
学会运用VisualC++6.0设计学生信息管理系统,从而达到了解设计一个小型应用系统的目的,提高适应实际,实践编程的能力。
2.设计依据及框图
2.1设计思想
学生信息管理系统是一个管理学生数据的服务平台,它应该包括登录界面,通过输入密码,核对正确进而进入主菜单界面,然后通过需要选择不同的操作,最终能够达到查询,增添,删除等功能。
2.2设计框图、用户界面
2.2.1通过对需求的分析和设计,我初步构造了程序的结构框图。
如图2.1:
2.2.2根据各模块功能的逐步展开与分析,我完成了程序的全部代码设计,详见附录Ⅰ。
在一次次的调试完善后,成功运行了这个学生管理系统。
1.这个系统是作为管理端存在的,为了保证信息的隐蔽性及安全性,防止人为破坏,所以设计一个登录界面,需要输入的密码核实正确后方能进入主菜单操作,以此来确保只有预先获得密码有管理权限的人才能使用该系统。
在此还设定了登录次数不得多于三次,否则强制退出程序。
这里将管理员输入的密码通过if…else语句判断是否等于code(预先定义在后台存储的),若相等则跳转至主界面,否则提示重新输入。
代码如下:
lab1:
system("cls");
cout<cout<<"\t\t\t请输入登录密码:
";
cin>>co;
if(co==code)
{gotolab2;}
else
{if(s<=3)
{s++;
if(s>=4)
{cout<<"已登录三次,请退出!
"<return0;}
else
gotolab1;}
}
2.在输入事先设定的密码,经检查正确,就到了主菜单界面,如下图;功能选择通过管理员输入数字,使用switch语句来判断接收,从而能够进入各个子菜单。
图2.1主菜单图
lab2:
system("cls");
cout<<"\t\t\t~*~*~欢迎使用学生信息管理系统~*~*~"<cout<<"1.录入信息"<cout<<"2.显示全部学生"<cout<<"3.计算平均成绩"<cout<<"4.删除一个学生"<cout<<"5.按年级输出学生信息"<cout<<"6.按性别输出学生信息"<cout<<"7.按姓名检索学生"<cout<<"8.按总分排序"<cout<<"9.结束程序运行"<cout<<"请输入您的选择(1~9):
";
cin>>getin;
switch(getin)
注:
lab2是一个标签,能通过之后的gotolab2从各级子菜单快速地跳转回来。
3.case1是录入信息菜单,p[i]是存储学生信息的数组对象,同样通过switch语句判断选择,可以不限次地分别录入一、二年级的学生信息,完成后自动保存并返回主菜单。
这里用类类型的指针变量指向已存在的最后一个记录,追加到最后一个记录后面,然后通过指针指向对象的成员函数set()从键盘上输入信息,用new开辟一段空间以存放该类型的对象,而统计创建的对象个数的变量i则进行自加运算,最后指针指回头结点。
增加学生信息,界面如下:
case1:
//录入信息
lab3:
system("cls");
cout<<"1.录入一年级生信息"<cout<<"2.录入二年级生信息"<cout<<"3.返回上一级菜单"<cout<<"请输入您的选择:
";
cin>>c1;
switch(c1)
{case1:
p[i]=newStudent1;
p[i]->set();
i++;
gotolab3;
case2:
p[i]=newStudent2;
p[i]->set();
i++;
gotolab3;
default:
gotolab2;
}
break;
图2.2录入信息2图
5.case2为显示信息菜单,先通过for循环语句并利用类指针,从类数组第一个对象开始调用display()来显示,直到全部学生显示完毕,最后指针指回头结点,停止操作并返回主菜单。
case2:
//显示全部信息
system("cls");
cout<<"学生信息\n"<<"学号姓名性别(male/female)语文英语数学年\n";
for(j=0;j
{p[j]->display();}
cout<<"\n\n输入任意数字返回主菜单:
";
cin>>c2;
switch(c2)
{case1:
case2:
case3:
default:
gotolab2}
图2.3信息显示图
6.case3计算平均成绩,输入需查询学生的学号,在for循环中用if语句及指针来搜寻与之匹配的信息,如果存在则通过函数getsum()取总成绩,再计算出平均成绩并用指针p[j]->display()输出,否则给出错误提示信息并返回主菜单返回主菜单后。
case3:
//计算平均成绩
lab4:
system("cls");
cout<cout<<"\t\t\t~*~*~计算平均成绩~*~*~"<cout<<"请输入学生学号:
";
intxh;
cin>>xh;
for(j=0;j
{if(p[j]->getnum()==xh)
{doublesum,ave;
sum=p[j]->getsum();
ave=sum/3;
cout<<"学号姓名语文英语数学平均成绩"<cout<
getnum()<<""<
getname()<<""<
getch()<<""<
geten()<<""<
getma()<<""<}
else
{cout<<"此学生不存在,请重新输入!
"<gotolab4;}
}
注:
这里的lab4为了便于返回重新查询设的标签,与gotolab4结合起来用。
图2.4查询成绩图
7.case4为删除学生,可以按照姓名或者学号删除,当管理员输入相应选择后,程序对应先通过查找记录,再对对应对象信息做删除,同样采用for循环跟if语句,每删除一个学生变量i就进行自减运算,是对象个数及时得到改正,最后指针指向头结点。
按照学号删除的代码如下:
intxuehao;
cout<<"输入学生的学号:
";
cin>>xuehao;
for(j=0;j
{
if(p[j]->getnum()==xuehao)
{
for(intdel=j;del
p[del]=p[del+1];
i--;}
}
cout<<"\n成功删除!
\n";
cout<<"\n\n输入任意数字返回主菜单:
";
cin>>c3;
switch(c3)
{case1:
case2:
case3:
default:
gotolab2;}
图2.5删除信息1图
8.case5是按年级输出学生,管理员选择所需年级后,用指针变量p[j]定位在年级号id所匹配的第一个对象处,接着执行display函数显示信息,j++后继续查找,用j
case5:
//按年级输出学生信息
system("cls");
cout<<"\t\t\t~*~*~按年级输出学生信息~*~*~"<cout<<"1.按一年级生输出学生信息"<cout<<"2.按二年级生输出学生信息"<cout<<"请输入您的选择:
";
cin>>c5;
switch(c5)
{case1:
cout<<"学号姓名性别语文英语数学年龄"<for(j=0;j
{if(p[j]->getid()==1)
p[j]->display();}
cout<<"\n输入任意数字返回主菜单:
";
cin>>c5;
switch(c5)
{
case1:
case2:
case3:
default:
gotolab2;
}
case2:
cout<<"学号姓名性别语文英语数学年龄"<for(j=0;j
{if(p[j]->getid()==2)
p[j]->display();}
cout<<"\n输入任意数字返回主菜单:
";
cin>>c5;
switch(c5)
{
case1:
case2:
case3:
default:
gotolab2;}
default:
cout<<"\n输入错误!
\n";
break;
cout<<"\n输入任意数字返回主菜单:
";
cin>>c5;
switch(c5)
{case1:
case2:
case3:
default:
gotolab2;}
}
图2.61年级输出图
9.case6按性别输出,也同样指针p[j]指向对象的函数getsex()取性别来与“female”或“male”比较,相等则调用display函数输出学生信息。
界面如下:
图2.7性别输出图
10.case7按姓名检索信息,管理员输入查询姓名后,系统利用类指针,从头开始p[i]->getname()==xingm(存放输入姓名的变量)查找配对的对象,如果if语句返回真值则执行display函数,接着switch接收任何数字返回主菜单,最后指针指向头结点。
case7:
system("cls");
cout<<"请输入学生的姓名:
";
cin>>xingm;
for(j=0;j
{if(p[j]->getname()==xingm)
{p[j]->display();}
}
cout<<"\n\n输入任意数字返回主菜单:
";
cin>>c7;
switch(c7)
{case1:
case2:
case3:
default:
gotolab2;}
11.case8按总分升序排序,使用for循环用指针变量p[ci]指向对象的成员函数getsum()取总分,将第一个对象依次和其他对象的比较,若前者总分大于后者,则通过两个中间变量htp和ztp把二者的学号与总分对换,以此类推直到排序完成。
接着用hao[j]、zong[j]输出信息。
case8:
//按总分排序
intci;
for(ci=0;ci
{
hao[ci]=p[ci]->getnum();
zong[ci]=p[ci]->getsum();
}
for(n=0;n
{
for(m=n+1;m
{
if(zong[n]>zong[m])
{
htp=hao[m];
hao[m]=hao[n];
hao[n]=htp;
ztp=zong[m];
zong[m]=zong[n];
zong[n]=ztp;
}
}
}
system("cls");
cout<cout<<"\t\t\t~*~*~按总分排序~*~*~"<cout<<"学生学号总分\n";
for(j=0;j
{
cout<}
cout<<"\n\n输入任意数字返回主菜单:
";
cin>>c8;
switch(c8)
{
case1:
case2:
case3:
default:
gotolab2;
}
图2.8总分排序图
12.case9退出程序,用system(″cls″)清屏,break语句跳出。
至此整个程序运行即switch语句结束。
最后,由于main函数定义为int型,要记得加上return0语句。
而程序中使用了输入输出流iostream、string类型等,头文件应该包括:
#include
#include
#include
#include
#include
usingnamespacestd;
这其中每个case后要加上break语句以便终止switch语句的执行,另外在一些经常需要跳转到的地方如主菜单处设为标签lab,之后使用goto语句即可跳转至此处。
3.各模块功能及主要模块的流程图
3.1各模块功能
1.整个程序中构造了一个学生基类,它应该包括学生的共有属性,而两个年级学生作为派生类,可以从基类中继承共有的成员,并在此基础上增加了年级的特性。
其中学生基类中的函数如表1:
表3.1基类模块表
Student
getid()
取年级号,用于识别一二年级
set()
在派生类中调用,录入信息
display()
在派生类中调用,显示信息
getnum()
取学号
getname()
取姓名
getsum()
取成绩总分
getsex()
取性别
getch()
取语文成绩
geten()
取英语成绩
getma()
取数学成绩
getborth()
取出生时间
该程序采用的是类类型来处理学生的所有基本信息。
通过对设计要求的分析构造基类Student,信息中应包含的学号、姓名、性别等就作为数据成员,而派生类一二年级学生继承了基类的一些属性,如姓名、学号等,但由于所处的年级不同,需要增加id号来识别年级。
而且它应该根据选择自动生成,不需要人为的录入。
所以getid()、set()、display()三个函数分别加上关键字virtual,使其成为纯虚函数,留待派生类定义调用同名函数却能实现不同的功能,这就体现了C++的多态性,既用不着重载函数,也能通过指针去调用派生类对象中的成员函数。
另外增加构造函数Student(),并对其数据成员进行赋初值,但id不用赋值,留待派生类分别进行定义。
而其余的8个函数则是用来取对象的数据。
代码如下:
classStudent
{public:
intid;//一二年级识别
intnum;
stringname;
stringsex;
doublech,en,ma;//成绩
intborth;
intage;
Student();
virtualintgetid()=0;//一二年级识别
virtualvoidset()=0;//纯虚函数,在派生类中调用
virtualvoiddisplay()=0;
intgetnum();//取学号
stringgetname();//取姓名
doublegetsum();//取总成绩
stringgetsex();//取性别
doublegetch();//取各科成绩
doublegeten();
doublegetma();
intgetborth();};
Student:
:
Student()//基类构造
{num=0;
name=”Noname";
ch=0;en=0;ma=0;
borth=1900;}
intStudent:
:
getnum()//取学号
{returnnum;}
stringStudent:
:
getname()
{returnname;}
stringStudent:
:
getsex()
{returnsex;}
doubleStudent:
:
getsum()
{returnch+en+ma;}
doubleStudent:
:
getch()
{returnch;}
doubleStudent:
:
geten()
{returnen;}
doubleStudent:
:
getma()
{returnma;}
intStudent:
:
getborth()
{returnborth;}
2.而在派生类中我分别定义了五个函数,主要是要体现录入、显示功能和重载,模块如表3.2:
表3.2学生1类模块表
Student1
getid()
取id=1,为一年级学生
set()
录入一年级学生信息
display()
显示一年级学生信息
ostream&operator<<(ostream&,Student1&)
一年级学生类中重载输出符
istream&operator>>(istream&,Student1&)
一年级学生类中重载输入符
表3.3学生2类模块表
Student2
getid()
取id=2,为二年级学生
set()
录入二年级学生信息
display()
显示二年级学生信息
ostream&operator<<(ostream&,Student2&)
二年级学生类中重载输出符
istream&operator>>(istream&,Student2&)
二年级学生类中重载输入符
两个派生类需采用公用派生,这样便于调用基类中的函数,以及为当中的重载输入输出符的友元函数做准备。
前三个函数分别调用了基类中的纯虚函数,并加以定义。
首先在派生类的构造函数Student1()中定义id为1,二年级类Student2的为2,通过函数getid()取值;其次函数set()、display()实现了录入和显示的功能。
后两个函数是对输入输出符的重载作为友元函数,这是因为在输入信息时,会不小心引入或者需要有空格,重载就是要允许空格的存在,添加记录时使用。
Student1代码如下:
classStudent1:
publicStudent//一年级学生类
{public:
intid;//一年级生识别
Student1();//Student1构造
intgetid();//一年级生识别
voidset();
voiddisplay();
friendostream&operator<<(ostream&,Student1&);
friendistream&operator>>(istream&,Student1&);};
voidStudent1:
:
set()//录入信息函数
{cout<<"输入一年级生信息\n"<<"学号姓名性别(male/female)语文英语数学出生年\n";
cin>>num>>name>>sex>>ch>>en>>ma>>borth;}
Student1:
:
Student1()//Student1构造
{id=1;}
intStudent1:
:
getid()
{returnid;}
voidStudent1:
:
display()//显示信息
{cout<<"\n一年级生:
\n"<}
//一年级生类中重载输入输出符
ostream&operator<<(ostream&out,Student1&stu)
{out<returnout;}
istream&operato