辽东学院自编教材
《程序设计语言Ⅱ》
实验指导书
齐文 编
(计算机科学与技术专业用)
辽东学院
20xx年12月
I
目 录
C++概论和输入输出 ......................................................... 1类和对象 ............................................................................ 6派生类与继承 .................................................................. 12多态性 .............................................................................. 16IO流与异常处理 ............................................................. 19面向对象程序设计方法与实例 ...................................... 23I 实验一 实验二 实验三 实验四 实验五 实验六
实验一 C++基础
实验类型: 实验课时: 2 指导教师: 时 间: 年 月 日 课 次: 第 节 教学周次:第 周 实验分室: 实验台号: 实 验 员: 一、
1.
2.
3.
4. 实验目的 掌握在集成开发环境中编辑、编译、连接和运行一个C++程序。 了解C++程序的基本框架,能够编写简单的C++程序。 熟悉c++中输入、输出操作。 掌握类的概念、类的定义格式、类与结构的关系、类的成员属性和类的封装性;
二、
三、 实验环境 实验内容 安装有Visual C++ 6.0和msdn帮助的计算机。
1. 结构化设计范例
#include <iostream>
using namespace std;
enum nations{hanzu,manzu,chaoxianzu};
struct student
{
int stuid;
char name[10];
nations nation;
};
void print(struct student *s)
{
cout<<"学号:"<<s->stuid<<endl<<"姓名:"<<s->name<<endl<<s->nation<<endl;
}
void main()
{
struct student s1;
s1.stuid=1;
strcpy(s1.name,"张三");
s1.nation=manzu;
print(&s1);
struct student s2;
s2.stuid=2;
strcpy(s2.name,"李四");
s2.nation=hanzu;
print(&s2);
}
#include <iostream>
using namespace std;
enum nations{hanzu,manzu,chaoxianzu};
struct student
{
public:
1
int stuid;
char name[10];
nations nation;
};
void print(struct student *s)
{
cout<<"学号:"<<s->stuid<<endl<<"姓名:"<<s->name<<endl<<s->nation<<endl;
}
void main()
{
struct student s1;
s1.stuid=1;
strcpy(s1.name,"张三");
s1.nation=manzu;
print(&s1);
struct student s2;
s2.stuid=2;
strcpy(s2.name,"李四");
s2.nation=hanzu;
print(&s2);
}
2.面向对象结构示例。
#include <iostream>
using namespace std;
enum nations{hanzu,manzu,chaoxianzu};
class student
{
public:
int stuid;
char name[10];
nations nation;
void print();
};
void student::print()
{
cout<<"学号:"<<stuid<<endl<<"姓名:"<<name<<endl<<nation<<endl;
}
void main()
{
student s1;
s1.stuid=1;
strcpy(s1.name,"张三");
s1.nation=hanzu;
s1.print();
student s2;
s2.stuid=2;
strcpy(s2.name,"李四");
s2.nation=manzu;
s2.print();
}
学号:1
2
姓名:张三
学号:2
姓名:李四
1
3、使用类封装及访问修饰符的作用,发现错误并写出编译提示
#include <iostream>
using namespace std;
class point {
int x, y;
public:
void setPoint(int vx, int vy){ x = vx; y = vy; }
};
void main()
{
point pt; // 创建point 类对象pt
pt.setPoint(10, 10); // 给point 对象pt 的坐标x, y 赋值
pt.x = 50; // 错误,不能访问私有成员
}
修改后,如果要求在main函数中输出x,y如何做,要求不许改变x和y的修饰符。 #include <iostream>
using namespace std;
class point {
public:
int x, y;
void setPoint(int vx, int vy){ x = vx; y = vy; }
void setPoint(){
cout<<"横坐标: "<<x<<endl<<"纵坐标: "<<y<<endl;
}
};
void main()
{
point pt; // 创建point 类对象pt
pt.setPoint(10, 10); // 给point 对象pt 的坐标x, y 赋值
pt.x = 50; // 错误,不能访问私有成员
pt.setPoint();
}
横坐标:50
3
纵坐标:10
4.定义一个win32 console application工程,新建一个名为t2.h的头文件和名为t2.cpp的源文件。内容如下:
t2.h
class point {
int x, y;
public:
void setPoint(int vx, int vy);
int getX();
int getY();
};
t2.cpp
#include <iostream>
#include "t2.h"
using namespace std;
void point::setPoint(int vx, int vy){ x = vx; y = vy; }
int point::getX(){return x;}
int point::getY(){return y;}
void main()
{
point pt; // 创建point 类对象pt
pt.setPoint(10, 10); // 给point 对象pt 的坐标x, y 赋值
point pt2; // 创建point 类对象pt
pt2.setPoint(20, 20); // 给point 对象pt2 的坐标x, y 赋值
cout<<pt.getX() <<" " <<pt.getY()<<endl ;
cout<<pt2.getX() <<" " <<pt2.getY()<<endl ;
}
编译t2.cpp 后运行。
写出内联函数的特点:
4
5
实验二 类和对象
实验类型: 实验课时: 4 指导教师: 时 间: 年 月 日 课 次: 第 节 教学周次:第 周 实验分室: 实验台号: 实 验 员:
四、实验目的
1. 掌握类的概念、类的定义格式、类与结构的关系、类的成员属性和类的封装性;
2. 掌握类对象的定义;
3. 理解类的成员的访问控制的含义,公有、私有和保护成员的区别;
4. 掌握构造函数和析构函数的含义与作用、定义方式和实现,能够根据要求正确定义和重载构造函数。能够根据给定的要求定义类并实现类的成员函数;
五、实验环境
安装有Visual C++ 6.0和msdn帮助的计算机。
六、实验内容
一、类定义封装的访问修饰符作用验证。
二、在类定义体内声明成员函数,而在类定义体外定义成员函数的实现代码。
三、构造函数定义和重载。
四、声明一个CPU类,包含等级(rank)、频率(freauency)、电压(voltage)等属性,有两个公有成员函数run、stop。其中rank为枚举类型,声明为enum CPU_Rank { p1=1,p2,p3,p4,p5,p6,p7},frequency为单位是MHz的整形数,voltage为浮点型的电压值。观察构造函数和析构函数的调用顺序。
五、声明一个简单的Computer类,有数据成员芯片(cpu)、内存(ram)、光驱(cdrom)等
等,有两个公在成员函数run、stop。cpu为CPU类的一个对象,ram为RAM类
的一个对象,cdrom为CDROM类的一个对象,声明并实现这个类。
七、实验步骤:
1、使用类封装及访问修饰符的作用,发现错误并写出编译提示
#include <iostream>
using namespace std;
class point {
int x, y;
public:
void setPoint(int vx, int vy){ x = vx; y = vy; }
};
void main()
{
point pt; // 创建point 类对象pt
pt.setPoint(10, 10); // 给point 对象pt 的坐标x, y 赋值
pt.x = 50; // 错误,不能访问私有成员
}
6
修改后,如果要求在main函数中输出x,y如何做,要求不许改变x和y的修饰符。
2、定义一个win32 console application工程,新建一个名为t2.h的头文件和名为t2.cpp的源文件。内容如下:
t2.h
class point {
int x, y;
public:
void setPoint(int vx, int vy);
int getX();
int getY();
};
t2.cpp
#include <iostream>
#include "t2.h"
using namespace std;
void point::setPoint(int vx, int vy){ x = vx; y = vy; }
int point::getX(){return x;}
int point::getY(){return y;}
void main()
{
point pt; // 创建point 类对象pt
pt.setPoint(10, 10); // 给point 对象pt 的坐标x, y 赋值
point pt2; // 创建point 类对象pt
pt2.setPoint(20, 20); // 给point 对象pt2 的坐标x, y 赋值
cout<<pt.getX() <<" " <<pt.getY()<<endl ;
cout<<pt2.getX() <<" " <<pt2.getY()<<endl ;
}
编译t2.cpp 后运行。
写出内联函数的特点:
7
2、
3、给上一题中point类增加两个构造函数,用于初始化x和y,一个是无参的将x和y初始化为0,另一个是有参的,将x和y初始化为指定的整数。在main中分别使用两个构造函数定义对象,并输出测试。
提示:构造函数
point(){x=y=0;}
point(int i,int j){x=i;y=j;}
测试:
point pt; // 创建point 类对象pt
cout<<pt.getX() <<" " <<pt.getY() ;
point pt2(30,30);
cout<<pt2.getX() <<" " <<pt2.getY() ;
4、源程序为:
#include <iostream.h>
enum CPU_Rank {p1=1,p2,p3,p4,p5,p6,p7};
class CPU
{
private:
CPU_Rank rank;
int freauency;
float voltage;
public:
CPU(CPU_Rank r, int f,float v)
{ rank=r;
8
freauency=f;
voltage=v;
cout<<" this is CPU construct program"<<endl;} ~CPU()
{
cout<<"this is CPU destroy function"<<endl; }
void run(){cout<< "the CPU is running"<<endl;} void stop(){cout<<"the CPU is Stopping"<<endl;} };
void main()
{
enum CPU_Rank rank;
rank=p5;
CPU cpu1(rank, 1024, 3.6);
cpu1.run();
cpu1.stop();
}
单步调试程序,并写出输出结果:
5、源程序为:
#include <iostream.h>
class RAM
{
private:
int rank;
int size;
public:
RAM( int r, int s)
{ rank=r;
size=s;}
void run(){cout<< "the RAM is running"<<endl;} void stop(){cout<<"the RAM is Stopping"<<endl;} };
class CDROM
9
{
private:
int rank;
int size;
public:
CDROM ( int r, int s)
{ rank=r;
size=s;}
void run(){cout<< "the CDROM is running"<<endl;} void stop(){cout<<"the CDROM is Stopping"<<endl;} };
class Computer
{
private:
CPU cpu;
RAM ram;
CDROM cdrom;
public:
{
cout<<"this is the Computer Construct"<<endl; }
void run()
{ cout<<"this is Computer is running"<<endl; cpu.run();
ram.run();
}
void stop ()
{ cout<<"this is Computer is stop"<<endl;
cpu.stop();
ram.stop();
}
};
void main()
{ enum CPU_Rank rank; Computer(CPU cp, RAM r, CDROM cd):cpu(cp),ram(r),cdrom(cd)
10
rank=p5;
CPU cpu1(rank, 1024, 3.6);
RAM ram(5,1024);
CDROM cdrom(5,1024);
Computer cp(cpu1,ram,cdrom);
cp.run();
cp.stop();
}
单步调试,分析每一个输出的原因:
11
实验三 派生类与继承
实验类型: 实验课时: 4 指导教师: 时 间: 年 月 日 课 次: 第 节 教学周次:第 周 实验分室: 实验台号: 实 验 员:
一、 实验目的
1.理解继承的含义,掌握派生类的定义方法和实现;
2.理解公有继承下基类成员对派生类成员和派生类对象的可见性,能正确地访问继承层次中的各种类成员;
3.理解保护成员在继承中的作用,能够在适当的时候选择使用保护成员以便派生类成员可以访问基类的部分非公开的成员;
4.理解虚函数在类的继承层次中的作用,虚函数的引入对程序运行时的影响,能够对使用虚函数的简单程序写出程序结果。
二、
三、 实验环境 实验内容和步骤 安装有Visual C++ 6.0和msdn帮助的计算机。
1.题目:先定义“点”类Point,再由“点”类派生出“圆”类Circle。
#include <iostream.h>
#define PI 3.14159
class Point // 定义“点”类
{
int x, y;
public:
Point(int a=0, int b=0)
{ x=a; y=b; }
void ShowPoint( )
{ cout<<"Point:("<<x<<','<<y<<")\n"; }
int Getx( )
{ return x; }
int Gety( )
{ return y; }
void Setxy(int a, int b)
{ x=a; y=b; }
};
class Circle: public Point // 定义“圆”类,公有继承
{
int r; // “圆”的半径
public:
Circle(int x, int y, int ra) : Point(x, y) // B
{ r = ra; }
void Setr(int ra)
12
{ r = ra; }
double Area( ) //求圆的面积
{ return PI*r*r; }
void Move(int x_offset, int y_offset) //将圆心坐标平移 { int x1=Getx( ); //存取基类的私有成员 int y1=Gety( ); // D
x1 += x_offset; y1 += y_offset; Setxy(x1, y1); // E
}
void ShowCircle( )
{
ShowPoint( ); // F
cout<<" Radius: "<<r<<'\t';
cout<<"Area: "<<Area( )<<endl; //G
}
};
void main( )
{
Circle c(1, 1, 1);
c.ShowCircle( );
c.Move(1, 2);
c.ShowCircle( );
c.Setxy(4, 5); //重新置圆心坐标
c.Setr(2); //重新置半径值
c.ShowCircle( );
}
写出如果Point类的x,y是public的话,Circle类的move方法可以如何改写?
2.题目: 先定义“点”类Point和“半径”类Radius,再由Point类和Radius类多重派生出“圆”类Circle。
#include <iostream.h>
#define PI 3.14159
class Point
{
protected: //A
int x, y;
public:
Point(int a=0, int b=0){ x=a; y=b; }
void ShowPoint( )
{ cout<<"Point:("<<x<<','<<y<<")\n";}
int Getx( ) { return x; }
13
int Gety( ) { return y; }
void Setxy(int a, int b){ x=a; y=b; }
};
class Radius
{
protected: //B
int r;
public:
Radius(int ra=0){ r = ra; }
void Setr(int ra){ r = ra; }
int Getr( ){ return r; }
};
class Circle : public Point, public Radius
{
public:
Circle(int x, int y, int ra) : Point(x, y), Radius(ra) //D { }
double Area( )
{ return PI*r*r; } //直接访问基类的保护成员
void Move(int x_offset, int y_offset)
{ x += x_offset; y += y_offset; }
void ShowCircle( )
{
ShowPoint( );
cout<<"Radius: "<<r<<'\t';
cout<<"Area: "<<Area( )<<endl;
}
};
void main( )
{
Circle c(1, 1, 1);
c.ShowCircle( );
c.Move(1, 2);
c.ShowCircle( );
c.Setxy(4, 5);
c.Setr(2);
c.ShowCircle( );
}
程序的运行结果为:
Point:(1, 1)
Radius: 1 Area: 3.14159
Point:(2, 3)
Radius: 1 Area: 3.14159
Point:(4, 5)
Radius: 2 Area: 12.5664
问题:
(1)为什么可以直接使用x,y,
14
(2)如果x,y在基类中是私有的行吗?
15
实验四 多态性
实验类型: 实验课时: 2 指导教师: 时 间: 年 月 日 课 次: 第 节 教学周次:第 周 实验分室: 实验台号: 实 验 员:
一、 实验目的
1.掌握虚函数的定义
2.纯虚函数和抽象类的使用
2.理解并掌握利用虚函数实现动态多态性和编写通用程序的方法。
二、
三、 实验环境 实验内容 安装有Visual C++ 6.0和msdn帮助的计算机。
1.定义一个车(vehicle)基类,有Run、Stop等成员函数,由此派生出自行车(bicycle)
类、汽车(motorcar)类,从bicycle和motorcar派生出摩托车(motorcycle)类,它们都有
Run、Stop等成员函数。观察虚函数的作用。
四、 实验步骤
1.编写程序定义一个车(vehicle)基类,有Run、Stop等成员函数,由此派生出自行车(bicycle)类、汽车(motorcar)类,从bicycle和motorcar派生出摩托车(motorcycle)类,它们都有Run、Stop等成员函数。在main()函数中定义vehicle、bicycle、motorcar、motorcycle的对象,调用其Run()、Stop()函数,观察其执行情况。再分别用vehicle类型的指针来调用这几个对象的成员函数,看看能否成功;把Run、Stop定义为虚函数,再试试看。
定义一个驾驶员类,类中增加drive(vehicle * c)方法,要求调用车辆的Run函数。测试是否能驾驶各种车辆。
#include<iostream>
using namespace std;
class vehicle
{
public:
virtual void run()
{
cout<<"vehicle run"<<endl;
}
virtual void stop()
{
cout<<"vehicle stop"<<endl;
}
};
class driver
{
virtual float drive(vehicle *c);
};
class bicycle:public vehicle
{public:
16
virtual void run()
{
cout<<"bicycle run"<<endl;
}
virtual void stop()
{
cout<<"bicycle stop"<<endl;
}
};
class motorcar:public vehicle
{
void run()
{
cout<<"motorcar run"<<endl;
}
void stop()
{
cout<<"motorcar stop"<<endl;
}
};
class motorcycle:virtual public bicycle,public motorcar {
void run()
{
cout<<"motorcycle run"<<endl;
}
void stop()
{
cout<<"motorcycle stop"<<endl;
}
};
void main()
{
vehicle *c;
bicycle b;
c=&b;
c->run();
c->stop ();
}
17
18
实验五 IO流与异常处理
实验类型: 实验课时: 2 指导教师: 时 间: 年 月 日 课 次: 第 节 教学周次:第 周 实验分室: 实验台号: 实 验 员:
一、 实验目的
1.熟悉流类库中常用的类及其成员函数的用法。
2.学习对文件的应用方法(二进制文件、文本文件)。
二、
三、 实验环境 实验内容 安装有Visual C++ 6.0和msdn帮助的计算机。
1.题目: 编一个程序用于复制文本文件
步骤1:
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
void main( )
{
char infilename[40], outfilename[40], ch;
cout<<"Please input an input file name: ";
cin>>infilename;
cout<<"Please input an output filename: ";
cin>>outfilename;
fstream infile(infilename, ios::in|ios::nocreate);
if(!infile)
{
cout<<"Can not open input file: "
<<infilename<<endl;
exit(1);
}
fstream outfile(outfilename, ios::out);
if(!outfile)
{
cout<<"Can not open output file: "
<<outfilename<<endl;
exit(2);
}
while(infile.get(ch))
outfile<<ch;
infile.close( );
outfile.close( );
}
写出两个if语句的作用及fstream类的常用方法:
19
2.题目:编一个程序从一个文本文件source.txt中读入若干整数,用选择法将这些数据排成升序,将排序后的结果写入另一个文件文本文件target.txt中。注意两个文件均在d盘的data文件夹中。
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
void sort(int *a, int n) //一般的选择法排序函数
{
int i, j, p, t;
for(i=0; i<n-1; i++)
{
p=i;
for(j=i+1; j<n; j++)
if(a[j]<a[p])
p=j;
if(p!=i)
{ t=a[i];a[i]=a[p]; a[p]=t; }
}
}
void main( )
{
int a[100], i, n;
fstream in, out; //若路径缺省,指当前目录
in.open("d:\\data\\source.txt", ios::in|ios::nocreate);
if(!in)
{
cout<<"Can not open source.txt!"<<endl;
exit(1);
}
out.open("d:\\data\\target.txt", ios::out);
if(!out)
{
cout<<"Can not open target.txt!"<<endl;
exit(2);
}
i=0;
while(in>>a[i]) i++; //循环结束后,i是整数的个数
sort(a, i );
n=i;
for(i=0; i<n; i++)
out<<a[i]<<endl;
20
in.close( );
out.close( );
}
在程序运行前,先准备好输入数据文件source.txt,放入d盘的data文件夹中,内容可以如下:
2 3 10 45
33 8 9 20
45 67 888 3
7 2 32 -2
0 -1
程序运行结束后,查看d盘的data文件夹中的结果文件target.txt内容是否正确。
将排序功能封装在Sort类中,程序应如何改写。
21
3. 定义一个异常类CException,有成员函数Reason(),用来显示异常的类型。在子函数 中触发异常,在主程序中处理异常,观察程序的执行流程。步骤如下:
在CException类的成员函数Reason()中用cout显示异常的类型,在函数fnl()中用throw语句触发异常,在主函数的try模块中调用fnl(),在catch模块中捕获异常。
22
实验六 面向对象程序设计方法与实例
实验类型: 实验课时: 2 指导教师: 时 间: 年 月 日 课 次: 第 节 教学周次:第 周 实验分室: 实验台号: 实 验 员: 一、
二、
三、 实验目的 实验环境 实验内容 1.综合应用所学技术解决实际问题。 安装有Visual C++ 6.0和msdn帮助的计算机。
要求使用所学技术解决一个复杂的问题,题目自选,尽量符合面向对象思想。技术要全面,设计要完善。
23
24
25