计算机专业学期三课程设计报告书.docx
《计算机专业学期三课程设计报告书.docx》由会员分享,可在线阅读,更多相关《计算机专业学期三课程设计报告书.docx(31页珍藏版)》请在冰点文库上搜索。
![计算机专业学期三课程设计报告书.docx](https://file1.bingdoc.com/fileroot1/2023-5/6/2f7ae6cb-ad40-482b-a1eb-461950f535ac/2f7ae6cb-ad40-482b-a1eb-461950f535ac1.gif)
计算机专业学期三课程设计报告书
《面向对象程序设计》
课
程
设
计
报
告
姓名小精灵
学号20080808
指导教师徐嘉斌
任务一
一、任务内容:
完成内容:
按照要求设计类(根据输出设计类)
设计类就是根据数据封装的要求,抽象出适合的类。
有如下测试程序和测试程序的输出结果,要求设计类Welcome。
(1)测试程序如下:
voidmain(){
Welcomewe;
Welcomeyou(we);
you.Display();
you.Set(“Thankyou.”);
cout<you.talk();
you.Display();
}
(2)测试程序的输出结果如下:
Welcome!
Thankyou.
输入:
Howaboutyou?
输出:
Howaboutyou?
输入:
Fine,thankyou.
输出:
Fine,thankyou.
输入:
OK
Allright
Goodbye!
OK
Goodbye!
Goodbye!
注:
后面5行为倒数第6行输出后接下去的输出内容。
(3)设计类Welcome的原则:
1)在头文件welcome.h中声明类
2)在welcome.cpp中实现类
3)使用内联函数定义Display()函数
4)演示文件名用学号作主名。
二、设计思路
由给出的代码来构造此程序。
开头部分,由Display输出Welcome,再用Get输出被Set存进的Thankyou。
利用循环函数While建立主体部分,输入OK时跳出循环。
结尾部分,因为给出的代码中建立了两个对象,所以调用析构函数时可直接输出两个Goodbye。
三、实现代码
//Welcome.h
#include
#include
usingnamespacestd;
classWelcome{
private:
chard[100];
public:
inlinevoidDisplay(){cout<voidSet(chara[]){strcpy(d,a);};
char*Get(){returnd;};
voidtalk();
Welcome(){};
Welcome(constWelcome&a);
~Welcome(){cout<<"Goodbye!
"<};
Welcome
d
inlinevoidDisplay()
voidSet(chara[])
char*Get()
voidtalk()
Welcome()
Welcome(constWelcome&w)
~Welcome()
//121-2.cpp
#include
#include
#include"Welcome.h"
usingnamespacestd;
voidmain()
{
Welcomewe;
Welcomeyou(we);
you.Display();
you.Set("Thankyou.");
cout<you.talk();
you.Display();
}
//121-1.cpp
#include
#include
#include"Welcome.h"
voidWelcome:
:
talk()
{
cout<<"输入:
";
cin.getline(d,100);
while(strcmp(d,"OK")!
=0)
{
cout<<"输出:
"<cout<<"输入:
";
cin.getline(d,100);
};
strcpy(d,"OK");
cout<<"Allright"<cout<<"Goodbye!
"<}
Welcome:
:
Welcome(constWelcome&a)
{
strcpy(d,a.d);
strcpy(d,"Welcome!
");
}
四、运行结果及分析
图1
分析:
前面先自动输出Welcome!
和Thankyou.,然后利用循环While函数重复用户的输入。
采用了多文件结构,利用构造函数、析构函数和拷贝构造函数将结果输出。
最后调用析构函数输出“Goodbye!
”
任务二
五、任务内容:
要求:
为分数定义一个类。
分数定义为两个整数之比。
将分数表示为int类型的两个值:
一个表示分子,一个表示分母。
重载输入>>和输出运算符<<,分数以1/2、-15/29这样的形式来输入和输出,注意分子、分母可能包含负号。
在分数类中,还应重载+、-、*、/运算符。
应有一个函数,对分数进行约分与规格化,在规格化之后,分母一定是正的,并且分子分母的最大分约数为1,如对4/-8正规化之后表示成-1/2。
仿照计算器的运算过程,采用计算器方式进行有关分数运算。
六、设计思路
(1)约分的关键是求分子分母的最大公约数,用Gcm(m,n)表示求m与n的最大公约数:
当n=0时,Gcm(m,n)=m
当n≠0时,Gcm(m,n)=Gcm(n,m%n)
可用递归编程实现Gcm(m,n)。
(2)分数的四则运算可按如下方式进行:
(3)利用Reduction函数将负号全都归到分子身上。
(4)Operation函数来实现当运算符输入错误时的提示。
(5)当除数为0时,main函数中有实现显示除数不能为0的设置。
N
Y
开始
输入除数、被除数和除号
分母为0
输出
输出“不能为除数,请重新输入。
结束
分数计算器
分数加法运算
分数减法运算
分数除法运算
分数乘法运算
异常处理报告
自行约分
负号转到分子
为负数加括号
七、实现代码
#include
#include
voidOperation(char&index);
usingnamespacestd;
classFraction
{
private:
intfz;
intfm;
intGcm(intm,intn);
public:
Fraction(intn=1,intd=1);
~Fraction(){};
voidReduction();
intGetFz(){returnfz;};
intGetFm(){returnfm;};
voidSetFz(intn);
voidSetFm(intd);
Fractionoperator+(Fraction&a);
Fractionoperator-(Fraction&a);
Fractionoperator*(Fraction&a);
Fractionoperator/(Fraction&a);
friendostream&operator<<(ostream&os,Fraction&s);
friendistream&operator>>(istream&is,Fraction&s);
};
intFraction:
:
Gcm(intm,intn)
{
if(n==0)
returnm;
elsereturnGcm(n,m%n);
}
voidFraction:
:
Reduction()
{
if(fm<0)
{fz=-fz;fm=-fm;}
intf=Gcm(abs(fz),fm);
fz=fz/f;
fm=fm/f;
}
voidOperation(char&index){
for(;;){
cout<<"请输入运算符:
";
cin>>index;
if(index=='+'||index=='-'||index=='*'||index=='/')
break;
else
cout<<"请输入正确的运算符:
";
}
}
Fraction:
:
Fraction(intn,
intd):
fz(n),fm(d){Reduction();}
voidFraction:
:
SetFz(intn){fz=n;}
voidFraction:
:
SetFm(intd){fm=d;}
istream&operator>>(istream&is,Fraction&s)
{
charch;
intm,n;
for(;;)
{
cout<<"请输入一个分数:
";
is>>m>>ch>>n;
s.SetFz(m);
s.SetFm(n);
if(ch=='/'&&n!
=0)
break;
else{
try{
if(ch!
='/')throw1;
if(n==0)throw2;
}
catch(inti){
if(i==1)
cout<<"输入格式错误,请重新输入!
"<
elseif(i==2)
cout<<"分母为0,请重新输入!
"<}
}
}
s.Reduction();
returnis;
}
ostream&operator<<(ostream&os,Fraction&s)
{
if(s.fz<0)
{
if(abs(s.fz)%s.fm==0)
os<<"("<elseif(abs(s.fz)>s.fm)
os<<"("<elseos<<"("<}
else{
if(s.fz%s.fm==0)
os<elseif(s.fz==0)
os<<0;
elseif(s.fz>s.fm)
os<又"<elseos<}
returnos;
}
FractionFraction:
:
operator+(Fraction&a)
{
Fractionr;
r.fz=fz*a.fm+fm*a.fz;
r.fm=fm*a.fm;
r.Reduction();
returnr;
}
FractionFraction:
:
operator-(Fraction&a)
{
Fractionr;
r.fz=fz*a.fm-fm*a.fz;
r.fm=fm*a.fm;
r.Reduction();
returnr;
}
FractionFraction:
:
operator*(Fraction&a)
{
Fractionr;
r.fz=fz*a.fz;
r.fm=fm*a.fm;
r.Reduction();
returnr;
}
FractionFraction:
:
operator/(Fraction&a)
{
Fractionr;
r.fz=fz*a.fm;
r.fm=fm*a.fz;
r.Reduction();
returnr;
}
intmain(){
Fractionobj1,obj2,r;
charindex='+';
inti;
charo='y';
for(;;)
{
if(o=='y')
{
cin>>obj1;
Operation(index);
cin>>obj2;
if(index=='+')
r=obj1+obj2;
elseif(index=='-')
r=obj1-obj2;
elseif(index=='*')
r=obj1*obj2;
elseif(index=='/')
{
for(;;)
{
i=obj2.GetFz();
if(i==0)
{
cout<<"不能为除数,请重新输入。
"<cin>>obj2;
}
elsebreak;
}
r=obj1/obj2;
}
cout<cout<<"是否继续(y/n)";
cin>>o;
}
elsebreak;
}
return0;
}
八、运行结果及分析
图2
分析:
第一个加法运算体现了约分的功能,第二个减法运算体现了假分数的自行转换功能,第三个乘法运算体现了给负数加括号的功能,第四个除法运算体现了自行将分母的负号提给分子的功能,以及最后五行体现了运算符错误的提示和分母为0的提示。
任务三
九、任务内容:
要求:
能够对文件进行存储和读取。
要求用一个结构记载学生属性,编写一个学生类以完成各种操作。
具体要求如下:
(1)有10个小学生,每个学生有数学、语文两门课,从键盘输入学生的学号、姓名及成绩,计算每个学生的平均成绩,将数据存入stud.dat中。
(2)学生的所有属性用一个结构进行描述。
(3)要求对“<<”、“>>”进行重载。
(4)选作要求:
可将两门课都不及格的学生信息从链表或数组中删除,并另存入bad.dat中;将学生姓名和平均成绩抽取出来。
(5)以下程序测试结果供参考(此处不列举)
一十、设计思路
建立两个类,并建立一个for循环来实现菜单的选择功能。
使用链表储存输入的信息,当选择查找与删除数据时,通过链表来寻找用户要寻找的数据。
开始
输入
学生信息
结束
功能选择
Y
输入0?
N
菜
单
菜单功能选择
增加原始记录
保存原始文件
显示各种文件
查找学生成绩
删除原始记录
修改学生信息
结束程序运行
一十一、实现代码
#include
#include
#include
#include
usingnamespacestd;
classStudent
{
public:
charname[20];
charId[20];
intCnum;
intMnum;
intsum;
Student*Next;
voidInput()
{
cout<<"\t\t名字:
";cin>>name;
cout<<"\t\t学号:
";cin>>Id;
cout<<"\t\t数学:
";cin>>Cnum;
cout<<"\t\t语文:
";cin>>Mnum;
sum=(Cnum+Mnum)/2;
}
voidReadFile(istream&in)
{in>>name>>Id>>Cnum>>Mnum>>sum;}
voidShow()
{cout<<};
classStudentmassage
{
public:
Studentmassage();
~Studentmassage();
voidShowMenu();
voidFind();
voidSave();
voidModifyItem();
voidRemoveItem();
voidSwap(Student*,Student*);
voidSort();
intListCount();
voidDisplay()
{
cout<<"姓名\t学号\t语文\t数学\t平均"<for(Student*p=Head->Next;p!
=End;p=p->Next)
p->Show();
cout<<"请按任意键";
getch();
}
voidAddItem()
{
End->Input();
End->Next=newStudent;
End=End->Next;
cout<<"添加成功!
"<cout<<"请按任意键";
getch();
}
private:
Student*Head,*End;
ifstreamin;
ofstreamout;
Student*FindItem(char*name)
{
for(Student*p=Head;p->Next!
=End;p=p->Next)
if(!
strcmp(p->Next->name,name))returnp;
returnNULL;
}
Student*FindID(char*Id)
{
for(Student*p=Head;p->Next!
=End;p=p->Next)
if(!
strcmp(p->Next->Id,Id))returnp;
returnNULL;
}
};
Studentmassage:
:
Studentmassage()
{
Head=newStudent;
Head->Next=newStudent;
End=Head->Next;
in.open("sort.txt");
if(!
in)
cout<else
{
while(!
in.eof())
{
End->ReadFile(in);
if(End->name[0]=='\0')break;
End->Next=newStudent;
End=End->Next;
}
in.close();
}
}
Studentmassage:
:
~Studentmassage()
{
Save();
for(Student*temp;Head->Next!
=End;)
{
temp=Head->Next;
Head->Next=Head->Next->Next;
deletetemp;
}
deleteHead,End;
}
voidStudentmassage:
:
ShowMenu()
{
cout<<"1.增加原始记录"<cout<<"2.显示各种文件"<cout<<"3.保存原始文件"<cout<<"4.查找学生成绩"<cout<<"5.删除原始记录"<cout<<"6.修改学生信息"<cout<<"0.结束程序运行"<cout<<"\n\t\t请选择:
";
}
voidStudentmassage:
:
Find()
{
charname[20],Id[10];
intx;
Student*p=NULL;
cout<<"\t\t1.按姓名查找\n\t\t2.按学号查找";
cin>>x;
switch(x)
{
case1:
{cout<<"\t\t请输入要查找的学生姓名:
";cin>>name;
if(p=FindItem(name))
{
p->Next->Show();
cout<<"请按任意键";
getch();
}
else
{
cout<<"\t\t没有该姓名的学生!
"<<'\n'<cout<<"请按任意键";
getch();
}
}break;
case2:
{
cout<<"\t\t输入要查找的学生学号:
";cin>>Id;
if(p=FindID(Id))
{
p->Next->Show();
cout<<"请按任意键";
getch();
}
else
{
cout<<"\t\t没有该学号的学生!
"<<'\n'<cout<<"请按任意键";
getch();
}
}break;
}
}
voidStudentmassage:
:
ModifyItem()
{
charname[20];
Student*p=NULL;
cout<<"\t\t请输入要修改的人的姓名:
";cin>>name;
if(p=FindItem(name))
{
cout<<"\t\t已找到学生的信息,请输入新的信息!
"<p->Next->Input();
cout<<"成功!
"<cout<<"请按任意键";
getch();
}
else
{
cout<<"\t\t没有!
"<cout<<"请按任意键";
getch();
}
}
voidStudentmassage:
:
RemoveItem()
{
charname[20];
Student*p=NULL,*temp=NULL;
cout<<"\t\t输入要删除的学生姓名:
"<>name;
if(p=FindItem(name))
{
temp=p->Next;
p->Next=p->Next->Next;
deletetemp;
cout<<"\t\t删除成功!
"<cout<<"请按任意键";
getch();
}
else
{
cout<<"\t\t没有!
"<cout<<"请按任意键";
getch();
}
}
voidStudentma