课程设计说明书课程名称C++项目设计设计题目企业人事信息管理系统学生姓名学号专业计算机应用指导教师李广松2011 年06 月30日目录一、系统开发相关情况 (1)(一)开发背景 (1)(二)系统开发的目标 (1)二、系统以及需求分析 (1)(一)系统目标 (1)(二)系统可行性分析 (1)1、技术可行性分析 (1)2、开发工具可行性分析 (2)三、程序功能描述以及模块结构 (2)(一)功能模块描述及主要类描述 (2)(二)程序流程图 (3)(三)数据结构表 (4)四、用户使用说明与调试结果 (4)(一)使用说明 (4)(二)调试结果 (4)(三)优缺点分析 (8)五、总结 (8)参考文献: (9)附录:职工信息管理系统源码(C++) (9)随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。
管理信息系统是一个不断发展的新型学科,任何一个单位要生存要发展,要高效率地把内部活动有机地组织起来,就必须建立与自身特点相适应的管理信息系统。
本文介绍了在Microsoft Visual C++ 6.0环境下开发一个职工信息管理系统的过程。
本系统界面友好,操作简单,比较实用。
一、系统开发相关情况(一)开发背景随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。
管理信息系统是一个不断发展的新型学科,任何一个单位要生存要发展,要高效率地把内部活动有机地组织起来,就必须建立与自身特点相适应的管理信息系统。
(二)系统开发的目标为了更好地适应我校的要求,进一步提供全方位的信息服务,职工信息管理系统在实施后应该能够达到以下的目标:★能够准确地记录职工的相关信息。
★系统界面友好、操作简单易行,查询灵活方便,数据储存安全可靠。
★系统维护安全、方便、可靠,并且能够实现实用性,先进性的要求。
二、系统以及需求分析(一)系统目标除了前面所述,我们所开发的系统还应该具有以下功能:⑴原始数据修改简单方便;⑵方便的数据查询;⑶删除数据方便简单,稳定性好;⑷数据计算自动完成,尽量减少人工干预;(二)系统可行性分析1、技术可行性分析由于本系统管理的对象单一,都是公司职工,所以涉及的计算过程不是很复杂。
现在学校用于学生管理的微机都是Pentium(R)4 CPU以上的机器,在存储量、速度方面都能满足各方面的要求。
在技术难度方面,由于有指导老师的指导和相关参考文献,因此完全可以实现。
2、开发工具可行性分析Microsoft Visual C++ 6.0简介Visual C++是一个功能强大的可视化软件开发工具。
自1993年Microsoft公司推出Visual C++1.0后,随着其新版本的不断问世,Visual C++已成为专业程序员进行软件开发的首选工具。
虽然微软公司推出了Visual C++.NET(Visual C++7.0),但它的应用的很大的局限性,只适用于Windows 2000,Windows XP和Windows NT4.0。
所以实际中,更多的是以Visual C++6.0为平台。
Visual C++6.0不仅是一个C++编译器,而且是一个基于Windows操作系统的可视化集成开发环境(integrated development environment,IDE)。
Visual C++6.0由许多组件组成,包括编辑器、调试器以及程序向导AppWizard、类向导Class Wizard等开发工具。
这些组件通过一个名为Developer Studio的组件集成为和谐的开发环境。
根据以上对开发工具的功能的了解,我们相信,依靠Microsoft Visual C++ 6.0能开发出我们所期待的系统。
因此,在开发工具方面是可行的。
三、程序功能描述以及模块结构(一)功能模块描述及主要类描述模块一:增加人员函数Add();增加职工基本信息。
模块二:删除人员函数Delete();删除指定的职工的基本信息以及薪酬。
模块三:修改人员函数Modify();修改指定的职工基本信息。
模块四:查询职工信息函数Query();查询指定的职工信息以及薪酬。
模块五:基础数据设置函数Set();设置五类职位的基本薪酬。
模块六:数据存盘,载入函数Save()以及Load();储存职工基本信息,薪酬以及五类职位的基本薪酬。
本系统采用了面向对象的程序设计方法。
所有的方法均以类为基础。
所涉及到的类包括:class Person 基本员工类;该类是一个基类,设置了属于保护类的职工基本属性,以及构造函数Person(char ID,char *Name,int Duty)。
可以给职工类型继承。
class Cservant文员类;由Person类继承而来。
定义了职工上个月的工作量Workload,获得工作量函数double GetWorkload(),传入工作量函数void SetWorkload(double Amount),以工作量计算薪酬函数void CalcSalary(),输出薪酬结果以及该类职工信息函数void Output ()。
class Salesman业务员类;同Cservant文员类。
class APman行政人员类;同Cservant文员类。
class CSman文员兼职业务人员类;同Cservant文员类。
class ACman行政人员兼职文员类;同Cservant文员类。
class Company 公司类;该类定义了前文所述六个模块功能的实现方法,链表的使用也包括其中。
此类的作能在于将所有功能模块集成并定义本系统使用的主要方法。
(二)程序流程图图 3-1 程序流程图表3-1 数据结构表四、用户使用说明与调试结果(一)使用说明这是一个关于职工信息管理系统,具有录入、输出、删除、查询、修改、保存、载入数据、计算总支出薪酬等功能,建立了一个含有工号、姓名、性别、联系方式、国籍、工作量等成员的类的变量class Person 。
系统中已预输入了5个职工的相关数据以及基本薪酬数据,调试是可按“4”键先查看输入的数据记录。
调试过程中,可按照有关提示进行相关操作:增加职工数据按“1”键;删除职工数据按“2”键;修改职工数据按“3”键;查询职工数据按“4”键;基础数据设置按“5”键;数据存盘按“6”键;数据装入按“7”键;退出系统按“8”键。
(二)调试结果★代码中运用了switch 语句调用各子函数,数字1、2、3、4、5、6、7、8等七个数字代表不同的指令。
★系统启动时,会自动在存放该系统的磁盘根目录之下装入两个数据文件:person.txt 和base.txt。
装入成功之后会显示“人员和基础数据已经装入…”。
调试时两个数据文件都已经写入部分数据,使用功能“4-查询职工信息”,显示如下:★各个职工最后的“工资”根据事前输入的职位,工作量自动计算生成。
并将所有的工资累加得到每个月需要支付的总工资。
以本次调试为例,系统显示“本月实发工资总数:14110元”。
★指令“1-增加人员”代表调用增加人员函数Add(),要求操作者输入职工的相关信息,管理系统会自动地开辟一个新的节点指针,把它的结点赋给预输入数据中的最后一个节点p2->next ,使其链接起来。
★指令“2-删除人员”代表调用删除人员函数Delete(),要求操作者输入职工的相关ID,系统根据操作者输出的ID,找出对应的记录,然后删除该职工的信息,如果删除的是第一个结点,则p1->next,指向第二个结点;下图示范了删除第一个节点之后的显示结果:★如果删除的是第i个(0< i <n)就把下一个结点地址赋给前一个结点地址;如果找不到对应的ID,则不会删除任何一个记录,并输出“未找到!”。
★指令“3-修改人员”代表调用修改人员函数Modify(),体统根据操作者输入的ID 找到对应的记录,将新输入的数据对应地赋给要修改的各成员。
包括调整职位,修改姓名,工作量。
★如果没有找到对应的ID,则不会修改任何一个记录,并输出“未输出!”。
★指令“4-查询职工信息”表示调用查询职工信息函数Query(),先输出所有的职工记录,然后系统根据输入的ID找到对应的数据,并输出总支出薪酬,如果没有找到对应的记录,则输出“未找到!”。
★指令“5-基础数据设置”表示调用基础数据设置函数Set(),要求操作员输入文员,行政人员,业务员的基本工资,以便计算每位职工的薪酬。
★指令“6-数据存盘”表示调用存盘函数Save(),输入“Y”或者“N”以进一步操作。
★指令“7-数据装入”表示调用载入函数Load(),系统直接导入数据。
(三)优缺点分析优点:★系统中包含了输入、输出、保存、删除、查询、修改等多种功能,系统操作灵活性较强,功能较强大;★可以随意地选择不同的指令进行操作;★自动计算本月应该支出的所有薪酬;★排版效果清晰明了,美观;★操作简单方便。
缺点:★在调用某些函数时,若没有找到对应记录的情况下,输出结果的处理不太完善,例如查询函数;★录入函数的设计不完善,这也是整个程序设计中最突出的问题。
五、总结本次设计我选择的题目是职工信息管理系统。
因为事先的计划非常明确,所以我们在完成这个设计的过程也是比较顺利的。
在系统分析和设计的部分仍然花了比较多的时间。
模块设计部分因为涉及功能的实现,要从抽象的设计转化成实际的代码,因此对于某项功能的实现方法都思考得比较详尽。
加上在开发系统之前,我阅读很多与本系统有相关内容的书籍以做参考,使得此次系统编写能顺利进行。
由于班里每个人都需要做一份设计,所以我们经常互相交流。
在交流的时候经常能够互相提出更好的建议。
经过对职工信息管理系统的分析与编写,我得到了很大的收获。
自主学习的必要性更是解决问题的基础。
这次设计使我重温了以前学过的各科知识,让我对C++编程有了更深刻的认识。
除了对系统作出正确的分析,实际的调查工作对系统的整体设计有着至关重要的作用。
所以在分析系统之前,我花了一些时间在公司的实际管理工作调查上。
也因为这样,如何编写代码逐渐变得明朗。
每一个功能模块经过调查后后,各个功能逐渐显露出来,然后,反复探讨,验证这项功能是否有存在的必要,是否可以改进得更好。
在这样的前提下,最后顺利完成了这份设计。
这次C++系统设计作业,提升了我分析问题的能力和思考问题的逻辑能力,更明白实际调研的重要性。
从这次设计学到的东西,相信会对我们日后的学习工作起到很大的指导作用参考文献:[1] 徐士良:C常用算法程序集,清华大学出版社,1995年版.[2] 洪永清:面向对象建模与设计,清华大学出版社,1993年版.[3] 谭浩强:C程序设计,清华大学出版社,1991年版.[4] 张国峰:C++语言及其程序设计教程,电子工业出版社,1997年版.[5] 侯捷:STL源码剖析,华中科技大学出版社,2002年版.[6] Bruce Eckel:Thinking in C++(2 nd ed),机械工业出版社,2003年版.附录:职工信息管理系统源码(C++)#include <iostream.h>#include <fstream.h>#include <ctype.h>#include <string.h>//全局数据,对象double CSalary; //文员的基本工资double SSalary; //业务员的基本工资double APSalary; //行政人员的基本工资int ID; //员工工号(要保证唯一)class Person //员工类{protected:int No; //编号char Name[20]; //姓名char Sex[10]; //性别char Tel[20]; //联系方式char Nation[30]; //国籍int Duty; //职位double Earning; //收入Person *next;public:Person(char ID,char *Name,int Duty){this->Duty=Duty;strcpy(this->Name,Name);this->No=ID;}virtual void CalcSalary()=0;virtual void Output()=0;friend class Company;};class Cservant:public Person //文员类{private:double Workload; //上个月完成工作量public:Cservant(char ID,char *Name,int Duty,double Workload):Person(ID,Name,Duty) {this->Workload=Workload;}double GetWorkload(){return Workload;}void SetWorkload(double Amount){this->Workload=Amount;}void CalcSalary()Earning=CSalary+(Workload-20)*20;}void Output(){CalcSalary();cout<<No<<"\t"<<Name<<"\t文员\t"<<"\t\t"<<Earning<<endl;}};class Salesman:public Person //业务员类{private:double Workload; //上个月完成工作量public:Salesman(char ID,char *Name,int Duty,double Workload):Person(ID,Name,Duty) {this->Workload=Workload;}double GetWorkload(){return Workload;}void SetWorkload(double Amount){this->Workload=Amount;}void CalcSalary(){Earning=SSalary+(Workload-15)*20+150; //150为业务补贴}void Output()CalcSalary();cout<<No<<"\t"<<Name<<"\t业务员\t"<<"\t\t"<<Earning<<endl;}};class ACman:public Person //行政人员兼职文员类{private:double Workload; //上个月完成工作量public:ACman(char ID,char *Name,int Duty,double Workload):Person(ID,Name,Duty) {this->Workload=Workload;}double GetWorkload(){return Workload;}void SetWorkload(double s){Workload=s;}void CalcSalary(){Earning=250+APSalary+CSalary+(Workload-15)*20;}void Output(){CalcSalary();cout<<No<<"\t"<<Name<<"\t行政人员兼职文员\t"<<Earning<<endl;}};class APman:public Person //行政人员类{public:APman(char ID,char *Name,int Duty):Person(ID,Name,Duty){}void CalcSalary(){Earning=APSalary+250;//250为行政补贴}void Output(){CalcSalary();cout<<No<<"\t"<<Name<<"\t行政人员\t\t"<<Earning<<endl;}};class CSman:public Person //文员兼职业务人员{private:double Workload;//文员兼职业务人员上个月完成工作量public:CSman(char ID,char *Name,int Duty,double Workload):Person(ID,Name,Duty) {this->Workload=Workload;}double GetWorkload(){return Workload;}void SetWorkload(double Amount){this->Workload=Amount;}void CalcSalary(){Earning=(Workload-25)*20+CSalary+150+SSalary;//150为业务补贴}void Output(){CalcSalary();cout<<No<<"\t"<<Name<<"\t文员兼职业务人员\t"<<Earning<<endl; }};class Company //公司类{private:Person *Worker; //员工表void Clear(); //清除内存中数据public:Company(){Worker=0;Load();}~Company(){Person *p;p=Worker;while(p){p=p->next;delete Worker;Worker=p;}Worker=0;}void Find(char Name[20]);//按姓名查找void Find(int ID);//按编号查找void Add(); //增加人员void Delete(); //删除人员void Modify(); //修改人员void Query(); //查询人员void Set(); //基础数据设置void Save(); //数据存盘(包括基础数据,人员数据)void Load(); //数据装入(包括基础数据,人员数据) };void Company::Clear() //清除内存中人员数据(内部使用) {Person* p=Worker;while(p){Worker=p->next;delete p;p=Worker;}}void Company::Find(char Name[20]){}void Company::Add(){Person *p; //新结点指针int Duty;char Name[20]; ``char Sex[10]; //性别char Tel[20]; //联系方式char Nation[30]; //国籍double Workload;cout<<"\n** 新增员工**\n";//输入员工信息cout<<"输入工号:"; cin>>ID;cout<<"输入职位(1-文员2-行政人员兼职文员3-文员兼职业务员4-行政人员5-业务员):"; cin>>Duty;cout<<"输入姓名:"; cin>>Name;cout<<"输入性别:"; cin>>Sex;cout<<"输入联系方式:"; cin>>Tel;cout<<"输入国籍:"; cin>>Nation;if(Duty!=4){cout<<"上个月完成工作量:"; cin>>Workload;}//创建新员工结点switch(Duty){case 1:p=new Cservant(ID,Name,Duty,Workload); break;case 2:p=new ACman(ID,Name,Duty,Workload); break;case 3:p=new CSman(ID,Name,Duty,Workload); break;case 4:p=new APman(ID,Name,Duty); break;case 5:p=new Salesman(ID,Name,Duty,Workload); break;}p->next=0;//员工结点加入链表if(Worker) //若已经存在结点{Person *p2;p2=Worker;while(p2->next) //查找尾结点{p2=p2->next;}p2->next=p; //连接}else //若不存在结点(表空){Worker=p; //连接}}void Company::Delete() //删除人员{int No;cout<<"\n** 删除员工**\n";cout<<"ID:"; cin>>No;//查找要删除的结点Person *p1,*p2; p1=Worker;while(p1){if(p1->No==No)break;else{p2=p1;p1=p1->next;}}//删除结点if(p1!=NULL)//若找到结点,则删除{if(p1==Worker) //若要删除的结点是第一个结点{Worker=p1->next;delete p1;}else //若要删除的结点是后续结点{p2->next=p1->next;delete p1;}cout<<"找到并删除\n";}else //未找到结点cout<<"未找到!\n";}void Company::Modify(){int No,Duty;char Name[20];double Workload;cout<<"\n** 修改员工**\n"; cout<<"ID:"; cin>>No;//查找要修改的结点Person *p1,*p2; p1=Worker; while(p1){if(p1->No==No)break;else{p2=p1;p1=p1->next;}}//修改结点if(p1!=NULL)//若找到结点{p1->Output();cout<<"调整职位(1-文员2-行政人员兼职文员3-文员兼职业务人员4-行政人员5-业务人员):"; cin>>Duty;if(p1->Duty!=Duty) //若职位发生变动{//修改其它数据cout<<"输入姓名:"; cin>>Name;if(Duty!=4){cout<<"上个月完成工作量:"; cin>>Workload;}//创建新员工结点Person *p3;switch(Duty){case 1:p3=new Cservant(p1->No,Name,Duty,Workload); break;case 2:p3=new ACman(p1->No,Name,Duty,Workload); break;case 3:p3=new CSman(p1->No,Name,Duty,Workload); break;case 4:p3=new APman(p1->No,Name,Duty); break;case 5:p3=new Salesman(p1->No,Name,Duty,Workload); break;}//员工结点替换到链表p3->next=p1->next;if(p1==Worker) //若要替换的结点是第一个结点Worker=p3;else //若要删除的结点是后续结点p2->next=p3;//删除原来的员工结点delete p1;}else //若职位没有变动{cout<<"输入姓名:"; cin>>p1->Name;if(Duty==1){cout<<"上个月完成工作量:"; cin>>Workload; ((Cservant *)p1)->SetWorkload(Workload);}else if(Duty==2){cout<<"上个月完成工作量:"; cin>>Workload; ((ACman *)p1)->SetWorkload(Workload);}else if(Duty==3){cout<<"上个月完成工作量:"; cin>>Workload; ((CSman *)p1)->SetWorkload(Workload);}else if (Duty==5){cout<<"上个月完成工作量:"; cin>>Workload; ((Salesman *)p1)->SetWorkload(Workload);}}cout<<"修改成功!\n";}else //未找到结点cout<<"未找到!\n";}void Company::Query()int chet,count(0);cout<<"\n** 查询职工信息以及本月销售信息**\n";cout<<"编号"<<"\t"<<"姓名"<<"\t"<<"职位"<<"\t\t\t"<<"工资(元/月)"<<endl;Person *p=Worker;double sum2=0; //工资总和while(p){p->Output();sum2+=p->Earning;p=p->next;}cout<<"本月实发工资总数:"<<sum2<<"元"<<endl;cout<<"请输入你要查询人员的编号:"; cin>>chet;Person *p4=Worker;while(p4){if(p4->No==chet){if(p4->Duty==1){((Cservant*)p4)->Output();count++;break;}else if(p4->Duty==2){((ACman*)p4)->Output();count++;break;}else if(p4->Duty==3)((CSman*)p4)->Output();count++;break;}else if(p4->Duty==4){((APman*)p4)->Output();count++;break;}else if(p4->Duty==5){((Salesman*)p4)->Output();count++;break;}}else{p4=p4->next;}}if(count==0) cout<<"未找到!"<<endl;}void Company::Set(){cout<<"\n** 设置基础数据**\n";cout<<"文员基本工资["<<CSalary<<"元]:"; cin>>CSalary;cout<<"行政人员基本工资["<<APSalary<<"元]:"; cin>>APSalary; cout<<"业务人员基本工资["<<SSalary<<"]:"; cin>>SSalary;cout<<"员工工号[>="<<ID<<"]:"; cin>>ID;void Company::Save() //数据存盘(包括基础数据,人员数据),均采用文本文件{ofstream fPerson,fBase;char c;cout<<"\n保存人员和基础数据,是否继续?[Y/N]:"; cin>>c;if(toupper(c)!='Y')return;//保存人员编号、姓名、职位fPerson.open("person.txt",ios::out);Person *p=Worker;while(p){fPerson<<p->No<<"\t"<<p->Name<<"\t"<<p->Duty<<"\t";if(p->Duty==1)fPerson<<((Cservant*)p)->GetWorkload()<<"\t";else if (p->Duty==2)fPerson<<((ACman*)p)->GetWorkload()<<"\t";else if (p->Duty==3)fPerson<<((CSman*)p)->GetWorkload()<<"\t";else if (p->Duty==5)fPerson<<((Salesman*)p)->GetWorkload()<<"\t";fPerson<<endl;p=p->next;}fPerson.close();//保存基础数据fBase.open("base.txt",ios::out);fBase<<"文员基本工资\t"<<CSalary<<endl;fBase<<"行政人员基本工资\t"<<APSalary<<endl;fBase<<"业务人员基本工资\t"<<SSalary<<endl;fBase<<"ID\t"<<ID<<endl;fPerson.close();cout<<"\n保存人员和基础数据已经完成...\n";}void Company::Load() //数据装入(包括基础数据,人员数据) {//基础数据装入ifstream fBase;char buf[80]; //buf用于保存数据文件中的注释字符串fBase.open("base.txt",ios::in);fBase>>buf>>CSalary; //文员基本工资fBase>>buf>>APSalary; //行政人员基本工资fBase>>buf>>SSalary; //业务人员基本工资fBase>>buf>>ID; //员工工号fBase.close();//清除内存人员数据Clear();//人员数据数据装入ifstream fPerson;Person *p=Worker;int No; char Name[20]; int Duty;double Workload;fPerson.open("person.txt",ios::in);//读一条记录fPerson>>No>>Name>>Duty;if(Duty!=4)fPerson>>Workload;while(fPerson.good()){//创建员工结点switch(Duty){case 1:p=new Cservant(No,Name,Duty,Workload); break; case 2:p=new ACman(No,Name,Duty,Workload); break; case 3:p=new CSman(No,Name,Duty,Workload); break; case 4:p=new APman(No,Name,Duty); break;case 5:p=new Salesman(No,Name,Duty,Workload); break;}p->next=0;//员工结点加入链表if(Worker) //若已经存在结点{Person *p2;p2=Worker;while(p2->next) //查找尾结点{p2=p2->next;}p2->next=p; //连接}else //若不存在结点(表空){Worker=p; //连接}//读下一条记录fPerson>>No>>Name>>Duty;if(Duty!=4)fPerson>>Workload;}fPerson.close();cout<<"\n人员和基础数据已经装入...\n"; }void main(){char c;Company a;do{cout<<"\n*** 职工信息管理系统***\n"; cout<<"1-增加人员\n";cout<<"2-删除人员\n";cout<<"3-修改人员\n";cout<<"4-查询职工信息\n";cout<<"5-基础数据设置\n";cout<<"6-数据存盘\n";cout<<"7-数据装入\n";cout<<"8-退出\t请选择(1-8):";cin>>c;switch(c){case '1': a.Add(); break;case '2': a.Delete();break;case '3': a.Modify();break;case '4': a.Query(); break;case '5': a.Set(); break;case '6': a.Save(); break;case '7': a.Load(); break;}}while(c!='8');}。