东北大学软件学院C++实验报告.docx
《东北大学软件学院C++实验报告.docx》由会员分享,可在线阅读,更多相关《东北大学软件学院C++实验报告.docx(23页珍藏版)》请在冰豆网上搜索。
东北大学软件学院C++实验报告
课程编号:
B080101020
《C++程序设计》
实验报告
姓名
学号
班级
指导教师
实验名称
《C++程序设计》综合实验开发与总结
开设学期
2016-2017学年第一学期
开设时间
第15周——第18周
报告日期
XXXX
评定成绩
评定人
XXX
评定日期
2016-01-12
东北大学软件学院
1.实验目的
实验一
1)学习编写简单的C++程序,并掌握C++程序的基本格式与规范。
2)练习重载函数的使用,掌握指针的使用方法。
3)学习标准输人输出及格式控制。
4)学习使用VC++的debug调试功能,使用stepinto追踪到函数内部。
实验二
1)学习并掌握类与对象的定义、使用、声明。
2)学习具有不同属性的数据成员与成员函数的访问方式。
3)理解构造函数和析构函数的定义与执行过程。
4)理解什么是运算符重载,掌握运算符重载的方法
实验三
1)学习定义和使用类的继承关系,定义派生类。
2)熟悉不同继承方式下对基类成员的访问控制。
3)学习使用虚函数实现动态多态性。
4)学习利用虚基类解决二义性问题。
实验四
1)加强对模板相关概念的理解,熟悉模板编程的语法。
2)学习编写简单的函数模板和类模板。
3)理解STL中容器、算法、迭代器的等概念,明确它们之间的关系。
4)掌握STL中Vector容器的使用方法。
2.实验环境
编译器:
MicrosoftVisualC++6.0
操作系统:
Windows10
3.实验内容与实验过程及分析
实验一
项目一:
内容:
使用动态数组完成编写并测试3X3矩阵转置函数,使用数组保存3X3矩阵,使用指针实现函数的功能。
代码:
main()
{
inti,j;
int**p;
p=newint*[3];
cout<<"输入矩阵的元素:
"<for(i=0;i<3;i++)
{
p[i]=newint[3];
for(j=0;j<3;j++)
{
cin>>p[i][j];
}
}
transpose(p);
cout<<"转置后的矩阵的为:
"<for(i=0;i<3;i++)
{
for(j=0;j<3;j++)
cout<
cout<}
delete[]p;
}
voidtranspose(int**matrix)
{
inti,k,j;
for(i=0;i<3;i++)
{
for(j=0;j<3;j++){
if(j>i){
k=matrix[j][i];
matrix[j][i]=matrix[i][j];
matrix[i][j]=k;
}
}
}
}
运行结果:
总结:
传递二维数组时候通过指针传递,可以对数组进行修改,方便了许多。
项目二:
内容:
编写程序,读写指定的文件,在每一行前加行号后,将结果输出到屏幕
代码:
voidwrite()
{
ofstreamout("test.txt");
if(out.is_open())
{
out<<"第一行\n";
out<<"第二行\n";
out<<"第三行\n";
out<<"第四行\n";
out<<"第五行\n";
out<<"第六行\n";
}
out.close();
}
voidread()
{
charbuffer[88];
ifstreamin("test.txt");
if(!
in.is_open())
{
cout<<"Erroropeningfile";
exit
(1);
}
while(!
in.eof())
{
in.getline(buffer,80);
cout<}
in.close();
}
voidmain()
{
cout<<"写文件"<write();
cout<<"读文件"<read();
system("pause");
}
运行结果:
总结:
学会了C++如何进行文件读写操作。
实验二
项目一:
内容:
以成员函数方式重载的“+”操作符的原型为:
CPointCPoint:
:
operator+(CPointpt);以全局函数方式重载的“-”操作符的原型为:
CPointoperator-(CPointpt1,CPointpt2);分析以成员函数方式和全局函数方式重载运行符的异同点。
重载的“>>”操作符的原型为:
istream&operator>>(istream&,CPoint&);重载的“<<”操作符的原型为:
ostream&operator>>(ostream&,CPoint);思考一下,重载的“>>”操作符和“<<”操作符能否作为CPoint类的成员函数来实现。
代码:
#include
#include
classCPoint
{
private:
intx,y;
staticintnCount;//nCount用于保存点的个数
public:
CPoint(intpx=0,intpy=0):
x(px),y(py)
{
}//构造函数,这个地方一定要写函数体内容,不然没有初始化的话会导致运行出错。
//CPoint(CPoint&);
~CPoint(){}//这是析构函数
intGETX()const
{
returnx;
}
intGETY()const
{
returny;
}
voidSetX(inta)
{
x=a;
}
voidSetY(intb)
{
y=b;
}
voidShowPoint()
{
cout<<"("<}
CPointoperator+(CPoint&cp2)
{
returnCPoint(GETX()+cp2.GETX(),GETY()+cp2.GETY());
};
friendCPointoperator-(CPoint&cp1,CPoint&cp2);//声明为友元函数
//输入输出运算符只能用友元函数重载
friendostream&operator<<(ostream&os,constCPoint&c);
friendistream&operator>>(istream&is,CPoint&c);
};
CPointoperator-(CPoint&cp1,CPoint&cp2)
{
returnCPoint(cp1.x-cp2.x,cp1.GETY()-cp2.GETY());
}//不要逗号
ostream&operator<<(ostream&os,constCPoint&c)
{
cout<<"重载<<直接输出对象得到:
"<<"("<returnos;
}
istream&operator>>(istream&is,CPoint&c)
{
is>>c.x>>c.y;
returnis;
}
classCLine
{
private:
CPointpt1,pt2;//pt1和pt2分别代表该线段的起点和终点
public:
CLine(){}//构造函数
CLine(intx1,inty1,intx2,inty2)
:
pt1(x1,y1),pt2(x2,y2)
{
}//必须以参数列表的形式来写,这样才能在声明的时候即初始化
CLine(CPointp1,CPointp2)
:
pt1(p1),pt2(p2)
{
}//必须以参数列表的形式来写,这样才能在声明的时候即初始化
doubleDistance()
{
inta=pt1.GETX()-pt2.GETX();
intb=pt1.GETY()-pt2.GETY();
doubledistance=sqrt(a*a+b*b);
returndistance;
}//计算该线段长度的成员函数
voidShowLine()
{
pt1.ShowPoint();
cout<<"-";
pt2.ShowPoint();
}
};
intmain()
{
CPointcp1(2,4);
CPointcp2(3,6);
CPointcp;
cout<<"两个点分别是";
cp1.ShowPoint();
cp2.ShowPoint();
cp=cp1+cp2;//两个点相加
cout<cout<<"两个点相加的结果是";
cp.ShowPoint();
cp=cp1-cp2;//两个点相减
cout<<"两个点相减的结果是";
cp.ShowPoint();
cout<CLineline1(1,3,5,0);
CLineline2(cp1,cp2);
cout<<"线段1是";
line1.ShowLine();
cout<cout<<"线段2是";
line2.ShowLine();
cout<cout<<"重载>>直接创建一个点,请输入两个值:
";
CPointLoadPoint;
cin>>LoadPoint;
cout<return0;
}
运行结果:
总结:
通过C++重载运算符的操作,可以让编程者自定义各个操作符的运算规则,简化了程序的编写逻辑和过程。
实验三
项目一:
内容:
使用实验2中的CPoint类,定义“空间中点”类如下:
classCThreePoint:
publicCPoint
{
private:
intz;
public:
CThreePoint();
CThreePoint(int,int,int);
intGetZ();
voidSetZ(intpz);
virtualvoidShowPoint();
};
完成该类中各成员函数的定义。
并利用VC调试工具观察含有继承关系类的构造函数和析构函数的执行情况。
代码:
#include
#include
classCPoint
{
private:
intx,y;
staticintnCount;//nCount用于保存点的个数
public:
CPoint(intpx=0,intpy=0):
x(px),y(py)
{
}//构造函数,这个地方一定要写函数体内容,不然没有初始化的话会导致运行出错。
//CPoint(CPoint&);
~CPoint(){}//这是析构函数
intGetX()const
{
returnx;
}
intGetY()const
{
returny;
}
voidSetX(inta)
{
x=a;
}
voidSetY(intb)
{
y=b;
}
virtualvoidShowPoint()//只有把它设置为虚函数时候才会出现(8,9)(3,2,5)的输出结果。
否则都是(8,9)(3,2)
{
cout<<"("<}
};
classCThreePoint:
publicCPoint
{
private:
intz;
public:
CThreePoint(){}//无参构造
CThreePoint(intpx=0,intpy=0,intpz=0)
{
SetX(px);
SetY(py);
z=pz;
}
intGetZ(){
returnz;}
voidSetZ(intpz){
z=pz;}
virtualvoidShowPoint()
{
cout<<"("<}
};
intmain()
{
CPointcp(8,9);
CThreePointctp(3,2,5);
CPoint*pt=&cp;
pt->ShowPoint();
pt=&ctp;
pt->ShowPoint();
return0;
}
运行结果:
总结:
C++中的继承、虚函数,多态,数据的封装,构造函数的实现等等各种面向对象程序设计的特性,方便进行现象化描述,通过对这一部分的学习,对于C++中的类的概念进一步巩固,基于对JAVA的学习,现在对于C++中多态、继承有了较多的了解。
项目二:
内容:
定义一个车(vehicle)基类,具有MaxSpeed、Weight等成员变量,Run、Stop等成员函数,由此派生出自行车(bicycle)类、汽车(motorcar)类。
自行车(bicycle)类有高度(Height)等属性,汽车(motorcar)类有座位数(SeatNum)等属性。
从bicycle和motorcar派生出摩托车(motorcycle)类,它们都有Run、Stop等成员函数。
代码:
#include
classvehicle
{
public:
intMaxSpeed;
intWeight;
virtualvoidRun(){
//执行该方法则开始运行
cout<<"开始运行,速度为"<}
virtualvoidStop()
{
//执行则停止运行
cout<<"停止运行"<}
};
classbicycle:
virtualpublicvehicle
{
public:
intHeight;
};
classmotorcar:
virtualpublicvehicle
{
public:
intSeatNum;
};
classmotorcycle:
publicbicycle,publicmotorcar
{
public:
intstyle;
};
main()
{
vehiclev;v.MaxSpeed=10;
bicycleb;b.MaxSpeed=5;
motorcarmcar;mcar.MaxSpeed=20;
motorcyclemb;mb.MaxSpeed=15;//如果不设置成为虚基类的话则该行代码编译不通过
vehicle*pt=&v;cout<<"vehicle";
pt->Run();pt->Stop();
pt=&b;cout<<"bicycle";
pt->Run();pt->Stop();
pt=&mcar;cout<<"motorcar";
pt->Run();pt->Stop();
pt=&mb;cout<<"motorcycle";
pt->Run();pt->Stop();
}
/**
vehicle开始运行,速度为10
停止运行
bicycle开始运行,速度为5
停止运行
motorcar开始运行,速度为20
停止运行
motorcycle开始运行,速度为15
停止运行
*/
运行结果:
总结:
学习了虚函数以及虚基类的使用以及作用。
虚函数、虚基类的使用对于C++的多态继承有更大的便利性。
实验四
项目一:
内容:
编写一个函数模板,要求它返回两个值中的最小者。
但同时要确保正确处理字符串。
代码:
#include
#include
usingnamespacestd;
template
Tmin(Ta,Tb)
{
Tc;
c=(a
a:
b;
returnc;
}
char*min(char*a,char*b)
{
returnstrcmp(a,b)<0?
a:
b;
}
voidmain()
{
cout<<"请输入两个整数:
"<chart1[100],t2[100];
cin>>t1>>t2;
cout<<"最小的是:
"<system("pause");
}
运行结果:
总结:
C++中模板的一个作用就是对同一类型的函数,进行不同参数类型的适配,比较人性化。
同时也方便了编程者进行对类库的封装,写出一个框架来。
项目二:
内容:
编写一程序,让用户自由地从键盘上输入整数,直到输入数字0时结束。
把用户输入的数据保存在模板类Vector定义的对象中,并对用户输入的所有数进行排序输出。
在向显示器进行输出时,要求用一下3种方式实现:
a)仅使用Vector的相关成员函数,不使用迭代器进行输出;
b)使用迭代器自己编程输出;
c)使用STL提供的通用算法for_each进行输出。
代码:
#include
#include
#include
usingnamespacestd;
voidshow(intn);
voidmain()
{
vectora;
intn=0;
do
{
cin>>n;
a.push_back(n);
}while(n!
=0);
for(intx=0;(unsignedint)xfor(inty=x;(unsignedint)yif(a[x]>a[y])
{
intz=a[x];
a[x]=a[y];
a[y]=z;
}
for(inti=0;(unsignedint)i<=a.size()-1;i++)
cout<cout<vector:
:
iteratorstart=a.begin();
vector:
:
iteratorend=a.end();
while(start!
=end)
{
cout<<*start<<"";
++start;
}
cout<for_each(a.begin(),a.end(),show);
cout<}
voidshow(intn)
{
cout<}
运行结果:
(输出结果包含三种实现方式)
总结:
C++中对于数据的存储有较多种方式,这里实现一种存储并排序输出。
掌握了Vector的使用及其技巧。
4.实验总结
从接触的第一门面向对象的语言JAVA开始,就对这种以对象形式来编程的方式产生了兴趣。
现在,又学习了C++,我对C++这种面向对象的编程语言的语法有了大致的掌握,由于学过JAVA语言,所以面向对象的思想掌握的不是很慢,但是比较吃力的就是C++中既融合了C的指针思想,又具有JAVA的引用变量思想,还有就是析构函数的引入,编程人员自己在内存中分配内存,而且用完之后要自己调用相应的函数去释放,所以操作实现起来稍显困难,不过这也是C++不同于JAVA之处——对机器配置要求不是太高。
C++编程的一些基本方法,是融合了C语言以及JAVA的,学会了C++语言的基本语法,面向对象类的设计思想,我也还学会了如何自己从网上寻找资源,如何自学新东西,相信这次实验学到的知识在我未来的学习个工作道路上都会是宝贵的财富,并且会在以后的编程之路上给予我较大的帮助。
5.思考题
实验一:
1.1.重载函数是通过什么来区分?
答:
参数类型、数量、顺序。
1.2.C++提供的输入输出操作与C语言的输入输出操作的异同点?
答:
同:
都可以通过输入设备输入并将数据显示出来。
异:
C++不用指定输出类型。
1.3.C++都定义了那些流?
他们分别与什么设备相连?
答:
C++定义了io流,与输入输出设备相连。
实验二:
2.1.类和结构体的区别是什么?
答:
成员访问权限不同,继承方式不同。
结构体不提供继承机制,类提供继承机制,实现代码复用;类可以实现多态,结构体不支持。
结构体中的数据默认方式是public的,而类是private的。
2.2.类的成员函数与普通的函数有何区别?
答:
类的成员函数是成员的特有方法,而普通函数能够随意被调用。
2.3.构造函数和析构函数的作用是什么?
答:
初始化对象,分配内存空间,释放内存空间。
2.4.类的访问控制权限有何意义?
答:
保护成员变量,可以将类中的具体细节封装起来。
实验三:
3.1.C++中有哪几种派生方式?
每种方式的派生类对基类成员的继承和访问控制属性是什么样的?
答:
有public,private,protected派生。
public派生,在派生类里和外面都可以直接调用基类的公有部分。
protected保护派生,在派生类里可以直接调用,但是在派生外面不可以调用。
private私有派生,在派生类里和外面都不可以直接调用,但可以用函数间接调用。
3.2.派生类对象和基类对象是什么样的关系?
派生类对象的构造函数和析构函数的执行顺序是怎样的?
答:
派生类对象是基类对象的扩展;
执行派生类构造函数时先执行基类构造函数,构造一个基类对象;
执行派生类析构函数时先执行派生类析构函数,再执行基类析构函数。
3.3.什么是多态?
在C++语言中,是如何实现多态的?
答:
多态是指接口的不同实现形式。
可以通过虚函数,抽象类,重载,覆盖,模板实现。
实验四:
4.1.谈谈使用模版进行编程的优点?
答:
使