c++实验报告

更新时间:2024-04-14 16:41:01 阅读量: 综合文库 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

实验一 类与对象

实验目的:

(1)

掌握类的定义和使用;掌握类对象的声明;练习具有不同访问属性的成员的访问方式;观察构造函数和析构函数的执行过程;

(2) (3)

学习类组合使用方法;

使用VC++的debug调试功能观察程序流程,跟踪观察类的构造函数、析构函数、成员函数的执行顺序。

仪器工具及材料

(1)

PC+Windows 2000+VC 6.0

内容及程序

?代码:

(1) 第一题:

#include

using namespace std;

int Max1(int a,int b);//求两个整数最大值 int Max1(int a,int b,int c); //求三个整数最大值 double Max1(double a,double b); //求两个双精度数

最大值

double Max1(double a,double b,double c); //求三个双精度数最大值

//主函数 int main() { int a,b,c; double x,y,z;

cout<<\求两个整数最大值,\\n输入两个整数:\ cin>>a>>b;

cout<<\最大值为:\

cout<<\求三个整数最大值,\\n输入三个整数:\ cin>>a>>b>>c;

cout<<\最大值为:\

cout<<\求两个双精度数最大值,\\n输入两个双精度数:\

cin>>x>>y;

cout<<\最大值为:\

cout<<\求三个双精度数最大值,\\n输入三个双精度数:\

cin>>x>>y>>z;

cout<<\最大值为:\

return 0; }

int Max1(int a,int b) {

return a>b?a:b; }

int Max1(int a,int b,int c) {

return a>b?(a>c?a:c):(b>c?b:c); }

double Max1(double a,double b)

{

return a>b?a:b; }

double Max1(double a,double b,double c) {

return a>b?(a>c?a:c):(b>c?b:c);

(2) 第二题:

}

#include using namespace std;

bool swap(int &a,int &b);//交换两个数值 //主函数 int main() { int a,b;

cout<<\请输入两个整数a,b:\ cin>>a>>b;

cout<<\当前a,b值为:a=\

swap(a,b);

cout<<\运行swap()交换a,b值\ cout<<\当前a,b值为:a=\ return 0; }

bool swap(int &a,int &b) { int temp; temp=a; a=b; b=temp;

return true; }

(3) 第三题:

// /CPU.CPP //类成员函数定义 #include\

int CPU::run() {

Rank=P4; frequency=150; voltage=4.55;

cout<<\正在运行。\\n 级别,频率,电压已改变!\

cout<<\级别=\频率=\

<<\电压=\

return 0; }

int CPU::stop() {

Rank=P1;

frequency=50; voltage=1.55;

cout<<\已停止。\\n 级别,频率,电压已改变!\

cout<<\级别=\频率=\

<<\电压=\

return 0; }

CPU::CPU(CPU &p) {

Rank=p.Rank; frequency=p.frequency; voltage=p.voltage;

cout<<\复制构造函数正在运行\

cout<<\级别=\频率=\

<<\电压=\}

//CPU.H //cpu类 #pragma once

#ifndef _CPU_H_ #define _CPU_H_

#include using namespace std;

enum CPU_Rank{P1=1,P2,P3,P4,P5,P6,P7}; //类定义 class CPU { public:

CPU():Rank(P1),frequency(0),voltage(0.0) { cout<<\构造函数运行\构造函数

~CPU(){ cout<<\析构函数运行\\n\

析构函数

private: };

#endif

///main.cpp #include\

CPU_Rank Rank;//级别 int frequency;//频率 double voltage;//电压 int run();//运行函数 int stop();//停止函数

CPU(CPU &p);//复制构造函数

//主函数 int main() {

cout<<\构造CPU对象cpu1:\ CPU cpu1; cpu1.run(); cpu1.stop();

cout<<\构造CPU对象cpu2:\ CPU cpu2(cpu1); return 0; }

(4) 第四题:

///Computer.cpp //类成员函数 #include\

Computer::Computer(CPU Cpu,RAM

Ram ,CDROM

Cdrom):cpu(Cpu),ram(Ram),cdrom(Cdrom)

{

cout<<\构造函数运行\\n\}

Computer::Computer(Computer &cmp) {

cpu=cmp.cpu; ram=cmp.ram; cdrom=cmp.cdrom;

cout<<\复制构造函数正在运行\\n\

}

Computer::~Computer() {

cout<<\析构函数运行\\n\ }

int Computer::run() {

cout<<\函数运行\\n\

return 0; }

int Computer::stop() {

cout<<\函数运行\\n\

return 0; }

int Computer::print() {

cout<<\成员变量值为:\\n\ cpu.Get();

cout<<\ cout<<\ cout<<\函数正在运行\\n\

return 0; }

///Computer.h

//类定义 #pragma once

#ifndef _COMPUTER_H_ #define _COMPUTER_H_

#include #include%using namespace std;

//RAM类定义 class RAM { public:

RAM(int size=0):ram_size(size){ cout<<\

RAM构造函数正在运行\\n\

RAM(RAM& r){ ram_size=r.ram_size;

cout<<\复制构造函数正在运行\\n\

~RAM(){ cout<<\析构函数正在运行

\\n\

int Get(){ return ram_size;}//返回成员值

private: };

//CDROM类定义 class CDROM { public:

CDROM(bool a=false):empty(a){ cout<<\int ram_size;//内存大小

CDROM构造函数正在运行\\n\

CDROM(CDROM &cd){ empty=cd.empty;

cout<<\复制构造函数正在运行\\n\

~CDROM(){ cout<<\析构函数正在

运行\\n\

bool Get(){ return empty;}//返回成员值

private: };

bool empty;//是否为空标记

//类定义 class Computer { public:

Computer(CPU Cpu,RAM Ram ,CDROM

Cdrom);//构造函数

//Computer():cpu(),ram(),cdrom(){ cout<<\空

构造函数正在运行\\n\构造函数重载 private: };

CPU cpu;//芯片 RAM ram;//内存 CDROM cdrom;//光驱

Computer(Computer &cmp);//复制构函数 ~Computer();//析构函数 int run(); int stop(); int print();

#endif

///CPU.CPP与CPU.H同第三题 ///main.cpp

#include\//主函数 int main() {

cout<<\定义CPU对象:\ CPU cpu;

cout<<\定义RAM对象:\ RAM ram;

cout<<\定义CDROM对象:\ CDROM cdrom;

cout<<\定义Computer对象computer:\

Computer computer(cpu,ram,cdrom); computer.print();

return 0; }

(5) 第五题:

////见第三题

结果及分析 ? 实验结果:

① 第一题:

② 第二题:

③ 第三题:

④ 第四题:

分析:每定义一个变量将调用构造函数,形参为其他的类的构造函数中,函数调用时将先调用形参类的复制构造函数生成形参对象,在初始化列表中初始化类对象时也会调用复制构造函数,构造函数运行结束会调用形参类的析构函数。 ⑤ 第五题:见第三题

实验二 类与对象

1. 目的要求:

1) 观察程序运行中变量的作用域、生存期和可见性; 2) 学习类的静态成员的使用;

3) 学习多文件结构在C++程序中的使用。

2. 实验内容:

1) 实现客户机(CLIENT)类。定义字符型静态数据成员ServerName,保存其服务器名称;整型静态数据成员ClientNum,记录已定义的客户数量;定义静态函数ChangeServerName()改变服务器名称。 ·代码: //client.h //client头文件 #pragma once

#ifndef _CLIENT_H_ #define _CLIENT_H_ //头文件

#include #include using namespace std;

//client类定义 class CLIENT {

public:

CLIENT();//构造函数 ~CLIENT();//析构函数

CLIENT(CLIENT &P);//复制构造函数

static bool ChangeServerName(string NewName);//改变服务

器名称

static int ShowClientNum(){ return ClientNum;}

户机数量 private: static string ServerName;//服务器名

static int ClientNum;//客户机数量

};

#endif

//client.cpp //类成员函数定义 #include\

//静态成员初始化

string CLIENT::ServerName(\int CLIENT::ClientNum=0;

//构造函数 CLIENT::CLIENT() {

ClientNum++;

//添加代码

//返回客

}

//析构函数

CLIENT::~CLIENT() {

ClientNum--; }

//复制构造函数

CLIENT::CLIENT(CLIENT &P) { }

//改变服务器名称

bool CLIENT::ChangeServerName(string NewName) {

ServerName=NewName;

cout<<\当前ServerName=\

return true; }

//test.cpp

#include\ //主函数 int main() {

CLIENT client1;//CLIENT对象 string name;//服务器名 int count;//客户机数量 //添加代码 //添加代码

cout<<\已定义CLIENT对象client1\ cout<<\请输入服务器名:\ cin>>name; //改变服务器名

CLIENT::ChangeServerName(name);

cout<<\

量:\ //定义client2

CLIENT client2;//CLIENT对象

cout<<\已定义CLIENT对象client2\ cout<<\请输入改变后服务器名:\ cin>>name;

CLIENT::ChangeServerName(name);

cout<<\

量:\ //增加客户机

cout<<\请输入要增加客户机数量:\ cin>>count;

CLIENT *newCLient=new CLIENT[count];

cout<<\

量:\ //删除客户机

delete[] newCLient;

cout<<\已删除新分配客户机对象\cout<<\

量:\

return 0; }

·运行结果:

2)利用多文件结构实现题目1),在头文件client.h中定义类,在 文件client.cpp中实现该类,在文件test.cpp 中测试这个类,观察相 应的成员变量取值的变化情况,要求ClientNum能够实时记录客户机对 象的数量。 ·代码: 同第一题 ·运行结果:

3)思考并回答以下概念: 类的静态数据成员,类的静态函数成员,多文件结构,文件包含。

a)

类的静态数据成员:static关键字开始的数据成员,为一个类所共有,公有状态下可通过对象名或类名访问,在类定义外初始化。

b)

类的静态函数成员:static关键字开始的函数成员,也为一个类所共有,可通过对象或类名访问,该函数不能直接访问非静态成员,需通过对象名访问。可直接访问静态成员与成员函数。

3. 主要仪器设备及软件:Windows 2000+VC 6.0

实验三 数组、指针与字符串实验

1. 目的要求:

1) 学习使用数组;学习字符串数据的组织和处理;学习标准C++库的使用; 2) 掌握指针的使用方法;练习通过debug观察指针的内容及其所指的对象的内容;练习通过动态内存分配实现动态数组,并体会指针在其中的作用;

3) 分别使用字符数组和标准C++库练习处理字符串的方法。

2.实验内容:

1) 编写一个类用于处理3×3矩阵转置,测试转置的效果,输出

转置前后的矩阵。 .代码: //Matrix.h //Matrix.h类声明

//实现任意类型矩阵的转置

#ifndef MATRIX_H #define MATRIX_H //头文件 #include #include

//声明模板类 template class ReveMatrix {

};

public:

ReveMatrix(){} ~ReveMatrix(){}

//转置n*m的矩阵

static T* getReverse(T* a,int n,int m);//返回指针类型

//函数定义

templateT* ReveMatrix::getReverse(T* a,int n,int m) {

T temp; int i,j;

vectorb(n*m,0);

for(i=0;i

for(j=0;j

b[i*n+j]=a[j*m+i]; } }

for(i=0;i

for(j=0;j

a[i*m+j]=b[i*m+j]; } }

return a; }

#endif

//函数重载实现n*n矩阵转置

/*

class ReveMatrix {

public:

ReveMatrix(){} ~ReveMatrix(){}

//转置n*m的矩阵

static void getReverse(double* a,int n,int m); static void getReverse(float* a,int n,int m); static void getReverse(int* a,int n,int m); static void getReverse(char* a,int n,int m); static void getReverse(string* a,int n,int m); };

void ReveMatrix::getReverse(double *a,int n,int m) {

double temp=0;

for(int i=0;i

for(int j=i;j

temp=*(a+i*m+j);

*(a+i*m+j)=*(a+j*n+i); *(a+j*n+i)=temp; } } }

void ReveMatrix::getReverse(float* a,int n,int m) {

float temp;

for(int i=0;i

for(int j=0;j

temp=*(a+i*m+j);

*(a+i*m+j)=*(a+j*n+i); *(a+j*n+i)=temp;

} } }

void ReveMatrix::getReverse(int *a,int n,int m) {

int temp;

for(int i=0;i

for(int j=0;j

temp=*(a+i*m+j);

*(a+i*m+j)=*(a+j*n+i); *(a+j*n+i)=temp; } } }

void ReveMatrix::getReverse(char* a,int n,int m) {

char temp;

for(int i=0;i

for(int j=0;j

temp=*(a+i*m+j);

*(a+i*m+j)=*(a+j*n+i); *(a+j*n+i)=temp; } } }

void ReveMatrix::getReverse(string* a,int n,int m) {

string temp;

for(int i=0;i

for(int j=0;j

temp=*(a+i*m+j);

*(a+i*m+j)=*(a+j*n+i); *(a+j*n+i)=temp;

} } } */

//main.h

#include #include%using namespace std;

//定义矩阵长宽

#define W 3 #define H 3

int main() {

int i,j;

int a[W][H]={1,2,3,4,5,6,7,8,9}; int *p;

char ch[W][H+1]={'a','b','c','d','e','f','g','h','i','j','k','l'}; char* pp;

cout<<\转置前矩阵:\for(i=0;i

for(j=0;j

cout<

cout<

}

}

p=ReveMatrix::getReverse((int*)a,W,H);

cout<<\转置后矩阵:\for(i=0;i

for(j=0;j

cout<

cout<

cout<<\转置前矩阵:\

for(i=0;i

for(j=0;j

cout<

cout<

pp=ReveMatrix::getReverse((char*)ch,W,H+1); cout<<\转置后矩阵:\for(i=0;i

for(j=0;j

cout<

cout<

return 0;

运行结果:

2)定义一个具有构造函数和析构函数的类,如实验一的CPU类, 定义一个CPU的对象数组,观察构造函数的析构函数的调用过程。 a) 代码: //CPU.H //cpu类

#ifndef _CPU_H_ #define _CPU_H_

#include using namespace std;

enum CPU_Rank{P1=1,P2,P3,P4,P5,P6,P7}; //类定义

class CPU {

public:

CPU():Rank(P1),frequency(0),voltage(0.0)

{

cout<<\构造函数运行\\n\

}//构造函数

CPU(CPU_Rank cr=P1,int fre=0,double vol=0.0) :Rank(cr),frequency(fre),voltage(vol) {

cout<<\重载构造函数运行\\n\

}//重载构造函数

~CPU(){ cout<<\析构函数运行\\n\析构函数 CPU(CPU &p);//复制构造函数 int run();//运行函数 int stop();//停止函数

private:

CPU_Rank Rank;//级别 int frequency;//频率 double voltage;//电压

};

#endif

//CPU.CPP //类成员函数定义 #include\

int CPU::run()

{

Rank=P4;

frequency=150; voltage=4.55;

cout<<\级别=\频率=\<<\电压=\

cout<<\正在运行。\\n 级别,频率,电压已改变!\

return 0; }

int CPU::stop() {

Rank=P1; frequency=50; voltage=1.55;

cout<<\级别=\频率=\<<\电压=\

cout<<\已停止。\\n 级别,频率,电压已改变!\

return 0; }

CPU::CPU(CPU &p) {

Rank=p.Rank;

frequency=p.frequency; voltage=p.voltage;

cout<<\复制构造函数正在运行\\n\

}

//main.h

#include\

int main() {

CPU_Rank cr=P2; CPU cpu1(cr,1,1.5);

CPU

cpu[10]={CPU(P4,4),CPU(cr),CPU(P3,2,2.5),CPU(cpu1),CPU(cr,4,4.5)};

return 0; }

b)运行结果:

3)利用动态内存分配的方式重新完成题目2)。 a)代码: //cpu.h //cpu类

#ifndef _CPU_H_ #define _CPU_H_

#include using namespace std;

enum CPU_Rank{P1=1,P2,P3,P4,P5,P6,P7}; //类定义

class CPU {

public:

CPU():Rank(P1),frequency(0),voltage(0.0) {

cout<<\构造函数运行\\n\

}//构造函数

CPU(CPU_Rank cr=P1,int fre=0,double vol=0.0) :Rank(cr),frequency(fre),voltage(vol) {

cout<<\重载构造函数运行\\n\

}//重载构造函数 ~CPU()

{ cout<<\析构函数运行\\n\析构函数 CPU(CPU &p);//复制构造函数

int run();//运行函数 int stop();//停止函数

private:

CPU_Rank Rank;//级别 int frequency;//频率 double voltage;//电压

};

#endif

//cpu.cpp //类成员函数定义 #include\

int CPU::run() {

Rank=P4;

frequency=150; voltage=4.55;

cout<<\级别=\频率=\<<\电压=\

cout<<\正在运行。\\n 级别,频率,电压已改变!\

return 0; }

int CPU::stop() {

Rank=P1; frequency=50; voltage=1.55;

cout<<\已停止。\\n 级别,频率,电压已改变!\cout<<\级别=\频率=\<<\电压=\

return 0; }

CPU::CPU(CPU &p) {

Rank=p.Rank;

frequency=p.frequency; voltage=p.voltage;

cout<<\复制构造函数正在运行\\n\}

//main.cpp

#include\

int main() {

CPU *cpu=new CPU[10]();

delete[] cpu;

return 0; } b)运行结果:

4)使用系统提供的string类定义字符串对象并初始化,实现从原始字符串中提取一个子串。 .代码:

//main.cpp

#include #include using namespace std;

//返回字符串从下标startpos开始的count个字符的子串 string substr(string str,int startpos,int count);

int main() {

string str=\

string substr1,substr2,substr3;

cout<<\源字符串为:\

substr1=str.substr(0,5); substr2=str.substr(2,5); substr3=substr(str,4,4);

cout<<\子串1=\cout<<\子串2=\cout<<\子串3=\

return 0; }

string substr(string str,int startpos,int count) {

string sub=\

int i,j=startpos+count;

for( i=startpos;i

sub+=str[i]; }

return sub; }

.运行结果:

5)选做:定义一个Point(二维点类)的对象数组,利用该数组实现直线的线性拟合。 a) 代码: //point.h //头文件

#ifndef POINT_H #define POINT_H //类定义

class Point {

public:

Point(float xx=0,float yy=0):x(xx),y(yy){} float getX()const{ return x;} float getY()const{ return y;}

private:

float x,y; };

#endif

//main.cpp

#include #include #include%using namespace std;

float lineFit(const Point Points[],int nPoint);

int main() {

Point p[10]={Point(6,10),Point(14,20),Point(26,30),Point(33,40), Point(46,50),Point(54,60),Point(67,70),Point(75,80),

Point(84,90),Point(100,100)};

float r=lineFit(p,10);

cout<<\相关系数为:\

return 0; }

//直线线性拟合

//Points点集合,nPoint点数

float lineFit(const Point Points[],int nPoint) {

float avgX=0,avgY=0; float lxx=0,lyy=0,lxy=0; int i; }

for( i=0;i

avgX+=Points[i].getX()/nPoint; avgY+=Points[i].getY()/nPoint; }

for( i=0;i

lxx+=(float)pow((Points[i].getX()-avgX),2); lyy+=(float)pow((Points[i].getY()-avgY),2);

lxy+=(Points[i].getX()-avgX)*(Points[i].getY()-avgY); }

cout<<\这些点能被直线:y=ax+b拟合\cout<<\

cout<<\

return static_cast(lxy/sqrt(lxx*lyy));//返回相关系数

b)运行结果:

6)选做:定义一个动态数组类。 a) 代码:

//main.cpp

#include using namespace std; //类定义

class TestClass {

public:

TestClass(){ t=NULL;num=0;}

TestClass(int n) {

if(n<1) {

t=NULL; num=0; } else {

//动态申请内存 t=new TestClass[n](); count+=n; num=n; }

}

TestClass(TestClass &tc) { //重新分配内存,深复制 t=new TestClass[count]; for(int i=0;i

t[i]=tc.t[i];//赋值

num=count; count+=count;

}

~TestClass(){delete[] t;cout<<\动态销毁了\

void test(){cout<

static int getCount(){ return count;}

void (*funptr)();//声明不会出错,赋值出错

private:

static int count; int num; TestClass* t; };

int TestClass::count=0;

int main() {

TestClass test(5);

//定义类成员函数指针,写在类定义里出错

个对象1 数

void (TestClass:: *ptr)()=&TestClass::test;//不能指向静态成员函

// int *p=&TestClass::count;//指向对象的静态成员,只能指向

公有

cout<<\共动态申请了\个对象\

return 0; }

b) 运行结果: //定义函数指针

int (*pstr2)()=&TestClass::getCount;

cout<<\共动态申请了\个对象\TestClass test2(test);

cout<<\共动态申请了\个对象\

思考并回答:数组,指针,对象数组,动态内存分配,默认构造函数,标准类库,字符串类 string,线性拟合。 标准类库: String类: 指针:

动态内存分配: 默认构造函数:

3. 主要仪器设备及软件:Windows 2000+VC 6.0

实验四 继承与派生

1. 目的要求:

1) 学习定义和使用类的继承关系,定义派生类;熟悉不同继承方式下对基类成员的访问控制;

2) 学习利用虚基类解决二义性问题。

2.实验内容:

1)定义一个基类Animal,有私有整型成员变量age,构造其派生类dog,在其成员函数SetAge(int n)中直接给age赋值,看看会有什么问题,把 age改为公有成员变量,还会有问题吗?编程试试看。 .代码: //man.cpp

#include

using namespace std;

class Animal { };

class dog:public Animal { }; int main() {

dog d; int age=10; public:

bool SetAge(int newAge) { }

int getAge() { }

return age;

age=newAge;//private不可访问,public可访问 return true; //private: public: int age;

}

.运行结果:

return 0;

cout<<\当前年龄为:\cout<<\设置年龄为\d.SetAge(age);

2) 定义一个基类BaseClass,有整型成员变量Number,构造其派生类DerivedClass,定义该派生类的对象,观察构造函数和析构函数的执行情况。 .代码: //man.cpp

#include using namespace std;

//2)定义一个基类BaseClass,有整型成员变量Number,构造其派生类DerivedClass,定义该派生类的对象,观察构造函数和析构函数的执行情况。 class BaseClass

{

public:

BaseClass():Number(0){ cout<<\构造函数运private: int Number;

行\

\};

class DerivedClass:public BaseClass { public:

\

\ }; int main() { }

return 0; DerivedClass d;

~DerivedClass(){ cout<<\析构和函数运行DerivedClass(){ cout<<\构造函数运行 ~BaseClass(){ cout<<\析构和函数运行

.运行结果:

3) 定义一个车(vehicle)基类,具有MaxSpeed、Weight等成员变量,Run、Stop等成员函数,由此派生出自行车(bicycle)类,汽车(motorcar)类。自行车(bicycle)类有高度(Height)等属性,汽车(motorcycle)类有座位数(SeatNum)等属性。从bicycle和motorcycle派生出摩托车(Motorcar)类,在继承过程中,注意把vehicle设置为虚基类。如果不把vehicle 设置为虚基类,会有什么问?编程实验及分析原因。 .代码:

//man.cpp

#include using namespace std;

class vehicle {

public:

vehicle():MaxSpeed(0),Weight(0){ cout<<\构造函数运行~vehicle(){ cout<<\析构函数运行\bool Run(){ cout<<\bool Stop(){ cout<<\\

本文来源:https://www.bwwdw.com/article/sqlp.html

Top