资源描述
实验一 C++基础
1.1 实验目的
1.了解并熟悉开发环境,学会调试程序;
2.熟悉C++中简单的标准输入输出函数的使用方法;
3.理解const修饰符的作用并学会应用;
4.理解内联函数的优缺点并学会其使用场合;
5.理解并学会函数重载;
6.理解并熟练掌握使用new和delete来分配内存;
7.理解并熟练掌握引用的使用方法。
1.2 实验内容
1.2.1 程序阅读
1.理解下面的程序并运行,然后回答问题。
#include <iostream.h>
int max_def(int x, int y)
{
return (x>y?x:y);
}
int max_def(int x, int y, int z)
{
int temp = 0;
return (temp=(x>y?x:y))>z?temp:z;
}
double max_def(double x, double y)
{
return (x>y?x:y);
}
int main()
{
int x1 = 0;
int x2 = 0;
double d1 = 0.0;
double d2 = 0.0;
x1 = max_def(5,6);
x2 = max_def(2,3,4);
d1 = max_def(2.1,5.6);
d2 = max_def(12.3,3.4,7.8);-----------------------------------------------------①
cout<<"x1="<<x1<<endl;
cout<<"x2="<<x2<<endl;
cout<<"d1="<<d1<<endl;
cout<<"d2="<<d2<<endl;--------------------------------------------------------②
return 1;
}
问题一:上述程序的输出结果是什么?
问题二:用的是哪个函数?
答:调用的函数是
int max_def(int x, int y, int z)
{
int temp = 0;
return (temp=(x>y?x:y))>z?temp:z;
}
问题三:②处的输出结果为什么是d2=12,而不是d2=12.3?
答:因为①处调用的是整型函数,d2在此函数中被转换为整型,小数点后面被删除。
2.理解下面的程序并运行,然后回答问题。
#include <iostream.h>
int main()
{
int *p1 = new int; -----------------------------------------------------①
int *p2 = new int(0); -----------------------------------------------------②
char *p3 = new char[10]; -----------------------------------------------------③
return 1;
}
问题一:①、②、③处动态申请内存分别代表什么意思?
答:①new动态分配存放一个整数的内存空间,并将其首地址赋给指针变量p1;②new动态分配存放一个整数的内存空间,并对其初始化赋值为0,并将其首地址赋给指针变量p2;③new动态分配存放10个字符型数组元素的内存空间,并将其首地址赋给指针变量p3。
问题二:该程序存在什么不合理的地方?。
答:程序结束时没有将分配的空间释放,应该使用delete函数释放内存。
3.理解下面的程序并运行,然后回答问题。
#include <iostream.h>
void swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
void swap(int *a, int *b)
{
int temp = *a;
*a = *b;
*b = temp;
}
int main()
{
int i = 5;
int j = 10;
cout<<"Before swap: i="<<i<<",j="<<j<<endl;
swap(i,j); -----------------------------------------------------①
cout<<"After the first swap: i="<<i<<",j="<<j<<endl;
swap(&i,&j); -----------------------------------------------------②
cout<<"After the second swap: i="<<i<<",j="<<j<<endl;
return 1;
}
问题一:输出结果是什么?
问题二:①处函数调用不能实现两个数的交换,而②可以,原因是什么?
答:①处调用的函数只是交换了局部变量a和b,并没有改变i和j的值;②处调用的函数使用了引用形参,i和j的值随着此处调用的函数中a和b的对换而对换。
问题三:②处调用的是哪个函数?
答:调用的函数是
void swap(int a, int b)
{
int temp = a;
a = b;
b = temp;
}
1.2.2 程序设计
1.定义两个重名函数,分别求出两点间平面距离和空间距离。
#include<iostream>
#include<cmath>
using namespace std;
int distance(int x1,int y1 ,int x2,int y2)
{
double dis;
dis=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
cout<<dis<<endl;
return dis;
}
int distance(int x1,int y1,int x2,int y2,int z1,int z2)
{
double dis;
dis=sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)+(z1-z2)*(z1-z2));
cout<<dis<<endl;
return dis;
}
void main()
{
int a;
int i,j,k,l,q,w,e,r,t,y;
cout<<"请输入平面两点坐标:"<<endl;
cin>>i>>j>>k>>l;
a=distance(i,j,k,l);
cout<<"请输入空间两点坐标"<<endl;
cin>>q>>w>>e>>r>>t>>y;
a=distance(q,w,e,r,t,y);
}
2. 设计一个函数:exch(),当调用exch (a,b,c)时,将a赋值给b,b赋值给c,c赋值给a,要求采用引用的方式来实现。
#include<iostream>
#include<cmath>
using namespace std;
void exch(int &m,int &n,int &p)
{
int temp=p;
p=n;
n=m;
m=temp;
}
int main()
{
int a=1,b=2,c=3;
cout<<"a="<<a<<"b="<<b<<"c="<<c<<endl;
exch(a,b,c);
cout<<"a="<<a<<"b="<<b<<"c="<<c<<endl;
return 0;
}
1.3 思考题
1. 自己设计一个程序,测试指向常量的指针,常指针,指向常量的常指针之间的区别。
#include <iostream>
using namespace std;
void main()
{
int a = 10;
int const *p = &a;
cout<<a<<endl;
cout<<*p<<endl;
int b = 20;
}
我们可以改变指针变量p所指向的内容,而不能改变p的地址空间,如 添加上p = &b;我们就会发现编译错误!指向常量的指针const ——int*p,特点是指针所保存的地址可以改变,然而指针所指向的值却不可以改变。同理,当添加*p = b时,会发生编译错误!指向常量的常指针
const int const*p特点是指针所保存的地址不可变,指针所指向的数值也不可变。
2. 编写一个函数,实现两个字符串变量的交换。
#include <iostream>
using namespace std;
void Exchg2(char *m,char *n)
{
char tmp = *m;
*m = *n;
*n = tmp;
}
void main()
{
char a = 'q';
char b = 'p';
cout<<"a="<<a<<" b="<<b<<endl;
Exchg2(&a, &b);
cout<<"a="<<a<<" b="<<b<<endl;
}
实验三 类和对象—构造函数与析构函数
3.1 实验目的
1.理解this指针的作用和用法;
2.掌握构造函数的定义和作用;
3.掌握构造函数的使用;
4.掌握拷贝构造函数的定义和使用;
5.掌握构造函数的重载;
6.掌握析构函数的定义和使用。
3.2 实验内容
3.2.1程序阅读
1.理解下面的程序并运行,然后回答后面的问题。
#include <iostream.h>
class CPoint
{
public:
void Set(int x,int y);
void Print();
private:
int x;
int y;
};
void CPoint::Set(int x,int y)
{
x = x;
y = y;
}
void CPoint::Print()
{
cout<<"x="<<x<<",y="<<y<<endl;
}
void main()
{
CPoint pt;
pt.Set(10,20);
pt.Print();
}
问题一:以上程序编译能通过吗?如果不能,原因是什么?
能通过编译。
问题二:以上程序的运行结构是否正确,如果不正确,分析为什么,如何改正?
结果不正确,因为Set函数中的形参与类中的相同产生错误,改为void CPoint::Set(int m,int n)。
2.理解下面的程序并运行,然后回答后面的问题。
#include <iostream.h>
class CPerson
{
public:
void Print();
private:
CPerson();
private:
int age;
char *name;
};
CPerson::CPerson()
{
}
void CPerson::Print()
{
cout<<"name="<<name<<",age="<<age<<endl;
}
void main()
{
CPerson ps(23,"张三");
ps.Print();
}
问题一:以上程序存在三个错误,在不改变主函数内容的前提下,试改正该程序。
#include<iostream>
#include<string>
using namespace std;
class CPerson
{
public:
void Print();
CPerson(int m,string n)
{
age=m;
name=n;
}
private:
int age;
string name;
};
void CPerson::Print()
{
cout<<"name="<<name<<",age="<<age<<endl;
}
void main()
{
CPerson ps(23,"张三");
ps.Print();
}
3.2.2 程序设计
1.设计实现一个CPoint类,满足以下要求:
a. 该类包含两个整型成员变量x(横坐标)和y(纵坐标),以及一个输出函数Print()用来输出横坐标和纵坐标,要求不可以在类的外部直接访问成员变量;
b.可以采用没有参数的构造函数初始化对象,此时的成员变量采用默认值0;
c.可以采用直接输入参数的方式来初始化该类的成员变量;
#include<iostream>
#include<ioamanip>
using namespace std;
class CPoint{
public:
void print();
CPoint(){x=0;y=0;}
point(int x1,int y1);
int GetX() {return x;}
int GetY() {return y;}
private:
int x;
int y;
};
void CPoint::print()
{
cout<<x<<setw(6)<<y<<endl;
}
CPoint::point(int x1,int y1)
{
x=x1;
y=y1;
}
void main()
{ CPoint p;
CPoint();
p.print();
p.point(1,2);
p.print();
p.GetX();
p.GetX();
}
3.3思考题
1.设计一个CStudent(学生)类,并使CStudent类具有以下特点:
a.有学生姓名、学号、程序设计、信号处理、数据结构三门课程的成绩;
b.全部信息由键盘输入;
c.通过成员函数统计学生平均成绩,当课程数量增加时,成员函数无须修改仍可以求取平均成绩;
d.输出学生的基本信息、各科成绩与平均成绩;
e.学生对象用链表存储;
f.统计不及格学生人数。
#include<iostream.h>
#include<iomanip.h>
#include<string.h>
#define N 3
#define M 3
class CStudent
{
public:
void setstudent(char *name,char *sn,float score[N]);
void showstudent();
private:
char Sname[10];
char Sno[8];
float Score[3];
float Avg;
float Sum;
int count;
};
void CStudent :: setstudent(char *name,char *sn,float score[N])
{
int i;
float Sum=0.0;
int count=0;
strcpy(Sname,name);
strcpy(Sno,sn);
for(i=0;i<N;i++)
{
Score[i]=score[i];
count++;
}
for(i=0;i<3;i++)
{
Sum=Sum+Score[i];
}
Avg=Sum/count;
}
void CStudent ::showstudent()
{
int i;
cout<<Sname<<setw(16)<<Sno<<setw(10);
for(i=0;i<3;i++)
cout<<Score[i]<<setw(10);
cout<<setw(12)<<Avg<<endl;
}
void main()
{
int i,j,k=0;
char name[10],no[8];
float score[N];
for(j=1;j<=M;j++)
{
cout<<"please input student["<<j<<"] name "<<setw(6);
cin>>name;
cout<<"please input student["<<j<<"] no "<<setw(6);
cin>>no;
cout<<"please input student["<<j<<"] score ";
for(i=0;i<N;i++)
cin>>score[i];
CStudent S1;
cout<<"student["<<j<<"] name"<<setw(6)<<"no";
cout<<setw(15)<<"程序设计"<<setw(10)<<"信号处理"<<setw(10)<<"数据结构"<<setw(10)<<"avg"<<endl;
S1.setstudent(name,no,score);
S1.showstudent();
if(score[i]<60)
k++;
}
cout<<"不及格人数:"<<k<<endl;
}
实验五 派生与继承—单基派生
5.1 实验目的
1.理解继承的概念;
2.理解公有派生、私有派生和保护派生;
3.理解单基派生类中构造函数和析构函数的执行顺序。
5.2 实验内容
5.2.1程序阅读
1.理解下面的程序并运行,然后回答后面的问题。
#include "iostream.h"
class CBase
{
public:
CBase(int a)
:a(a)
{
}
protected:
void print()
{
cout<<"a="<<a<<endl;
}
private:
int a;
};
class CDerive : public CBase
{
public:
void print()
{
CBase::print();
cout<<"b="<<b<<endl;
}
private:
int b;
};
void main()
{
CDerive d;
d.print();
CBase b;
b.print();
}
问题一:以上程序有两个错误,试指出来,并改正之。
答:派生类CDerive中没有定义CDerive(),主函数中没有给d,b对象赋值。
#include "iostream.h"
class CBase
{
public:
CBase(int a)
:a(a)
{
}
void print()
{
cout<<"a="<<a<<endl;
}
private:
int a;
};
class CDerive : public CBase
{
public:
CDerive(int a,int c)
:CBase(a)
{
b=c;
}
void print()
{
CBase::print();
cout<<"b="<<b<<endl;
}
private:
int b;
};
void main()
{
CDerive d(1,3);
d.print();
CBase b(2);
b.print();
}
2.理解下面的程序并运行,然后回答后面的问题。
#include "iostream.h"
class CBase
{
public:
CBase(int a)
:a(a)
{
cout<<"base structure"<<endl;
}
~CBase()
{
cout<<"base destructure"<<endl;
}
void print()
{
cout<<"a="<<a<<endl;
}
protected:
int a;
};
class CDerive : public CBase
{
public:
CDerive(int a, int b,int c)
:CBase(a),b(b),c(c)
{
cout<<"derive structure"<<endl;
}
~CDerive()
{
cout<<"derive destructure"<<endl;
}
void print()
{
CBase::print();
cout<<"b.a="<<b.a<<endl;
cout<<"c="<<c<<endl;
}
private:
CBase b;
int c;
};
void main()
{
CDerive d(1,2,3); -----------------------------------------------------①
d.print();
}
问题一:以上程序的输出结果是什么,为什么?
答:程序错误,不能输出结果。“cout<<"b.a="<<b.a<<endl;”这个语句中调用了基类中的保护参数a。
问题二:①处语句执行完后,d.b.a的值为多少?
答:b.a=2。
实验七 多态性—函数与运算符重载
7.1 实验目的
1.理解静态联编和动态联编的概念;
2.掌握成员函数方式运算符重载;
3.掌握友元函数方式运算符重载;
4.掌握++、--、=运算符的重载。
7.2 实验内容
7.2.1程序阅读
1.理解下面的程序并运行,然后回答后面的问题。
#include "iostream.h"
class CComplex
{
public:
CComplex()
{
real = 0;
imag = 0;
}
CComplex(int x,int y)
{
real = x;
imag = y;
}
int real;
int imag;
CComplex operator + (CComplex obj1)-----------------------------------------------①
{
CComplex obj2(real + obj1.real, imag + obj1.imag);
return obj2;
}
};
void main()
{
CComplex obj1(100,30);
CComplex obj2(20, 30);
CComplex obj;
obj = obj1+obj2; ------------------------------------------------------------------②
cout << obj.real <<endl;
cout << obj.imag << endl;
}
问题一:①处的运算符重载,为什么该函数的返回值要设计成CComplex类型?
答:运算符重载函数的返回值与其操作类的类型相同。
问题二:②处的运算符重载函数调用就相当于“obj=operator+(obj1,obj2);”,请问CComplex类中的运算符重载函数为什么只有一个参数?
答:因为另一个参数是隐含调用,是CComplex类的当前对象。它通过this指针隐含地进行传递。
2.理解下面的程序并运行,然后回答后面的问题。
#include "iostream.h"
class CComplex
{
public:
CComplex()
{
real = 0.0;
imag = 0.0;
}
CComplex(float x, float y)
{
real = x;
imag = y;
}
CComplex operator + (CComplex &obj1, CComplex &obj2)
{
CComplex obj3(obj1.real + obj2.real, obj1.imag + obj2.imag);
return obj3;
}
CComplex &operator++(CComplex &obj)
{
obj.real += 1;
obj.imag +=1;
return obj;
}
void print()
{
cout<<real<<"+"<<imag<<"i"<<endl;
}
private:
float real;
float imag;
};
CComplex &operator--(CComplex &x)
{
x.real -= 1;
x.imag -= 1;
return x;
}
void main()
{
CComplex obj1(2.1,3.2);
CComplex obj2(3.6,2.5);
cout<<"obj1=";
obj1.print();
cout<<"obj2=";
obj2.print();
CComplex obj3 = obj1 + obj2;
cout<<"befor++, obj3=";
obj3.print();
++obj3;
cout<<"after++, obj3=";
obj3.print();
--obj3;
cout<<"after--, obj3=";
obj3.print();
CComplex obj4 = ++obj3;
cout<<"obj4=";
obj4.print();
}
问题一:以上程序中的三个运算符重载都有错误,试改正并分析输出结果。
#include "iostream.h"
class CComplex
{
public:
CComplex()
{
real = 0.0;
imag = 0.0;
}
CComplex(float x, float y)
{
real = x;
imag = y;
}
CComplex operator + (CComplex &obj1)
{
CComplex obj2(real + obj1.real, imag + obj1.imag);
return obj2;
}
friend CComplex operator++(CComplex &obj)
{
obj.real += 1;
obj.imag += 1;
return obj;
}
CComplex operator--();
void print()
{
cout << real << "+" << imag << "i" << endl;
}
private:
float real;
float imag;
};
CComplex CComplex::operator--()
{
real -= 1;
imag -= 1;
return (*this);
}
void main()
{
CComplex obj1(2.1, 3.2);
CComplex obj2(3.6, 2.5);
cout << "obj1=";
obj1.print();
cout << "obj2=";
obj2.print();
CComplex obj3 = obj1 + obj2;
cout << "befor++, obj3=";
obj3.print();
++obj3;
cout << "after++, obj3=";
obj3.print();
--obj3;
cout << "after--, obj3=";
obj3.print();
CComplex obj4 = ++obj3;
cout << "obj4=";
CComplex obj4.print();
}
结果:
obj1=2.1+3.2;
obj2=3.1+2.5;
obj3=5.7+5.7;
after++obj3=1.7+1.7;
after--obj3=5.7+5.7;
obj4=1.7+1.7;
7.2.2 程序设计
1. 把7.2.1中第一道题的程序改造成采取友元函数重载方式来实现“+”运算符,并采取友元函数重载方式增加前置和后置“++”以及“--”运算符重载,并设计主函数来验证重载运算符的用法。
#include<iostream>
using namespace std;
{
public:
CComplex()
{
real=0;
imag=0;
}
CComplex(int x,int y)
{
real=x;
imag=y;
}
friend CComplex operator+(CComplex obj1,CComplex obj2)
{
return CComplex(obj1.real-obj2.real,obj1.imag-obj2.imag);
}
friend CComplex operator++(CComplex obj)
{
obj.real+=1;
obj.imag+=1;
return(*this);
}
friend CComplex operator+(CComplex obj1,CComplex obj2)
{
return CComplex(obj1.real-obj2.real,obj1.imag-obj2.imag);
}
int real;
int imag;
}
void show()
{
cout<<real<<"+"<<imag<<"i"<<endl;
}
void main()
{
CComplex obj1(1,2);
CComplex obj2(3,4);
CComplex obj;
obj=obj1+obj2;
obj.show();
++obj;
obj.show();
obj=obj1-obj2;
obj.show();
return 0;
}
7.3思考题
1.定义CPoint类,有两个成员变量:横坐标(x)和纵坐标(y),对CPoint类重载“++”(自增运算符)、“--”(自减运算符),实现对坐标值的改变。(每个函数均采用友元禾成员函数实现)
#include<iostream>
using namespace std;
class CPoint
{
public:
int x;
int y;
CPoint()
{
x=0;
y=0;
}
CPoint(int x,int y)
{
x=x1;
y=y2;
}
friend CPoint operator++(CPoint obj);
{
obj.x+=1;
obj.y+=1;
return (*this);
}
friend CPoint operator--(CPoint obj);
{
obj.x-=1;
obj.y-=1;
return (*this)
}
int x;
int y;
}
void show()
{
cout<<"("<<x<<","<<y<<")"<<endl;
}
void main()
{
CPoint obj(1,2);
obj.show();
obj++;
obj.show();
obj--;
obj.show();
return 0;
}
24 / 25
展开阅读全文