C++:【练习题】类和对象

习题1

1.1 题目:

下面是一个类的测试程序,设计出能使用如下测试程序的类。

int main()
{
	Test a, b;
	a.Init(68,55);
	b.Init(18,36);
	a.Print();
	b.Print();
	return 0;
}

其执行结果为:

68-55=13
18-36=-18

1.2 解题思路:

  • 1、 构建Test类。
  • 2、 分析Test类内的方法分别是做什么用的,成员变量需要什么样的数据结构来存储。
  • 3、 编写程序并进行调试。

1.3 代码及注释:

#include<iostream>
using namespace std;

class Test {
private:
	int a;
	int b;
public:
	void Init(int a1, int b1) {
		//存储两个int型的数据
		a = a1;
		b = b1;
	}
	void Print() {
		//输出存储的数据并进行减法操作
		cout << a << "-" << b << "=" << a - b << endl;
	}
};

int main()
{
	Test a, b;
	a.Init(68, 55);
	b.Init(18, 36);
	a.Print();
	b.Print();
	return 0;
}

1.4 程序运行结果分析:

68-55=13
18-36=-18
请按任意键继续. . .

验证可得程序执行正确。

习题2

2.1 题目:

设计一个立方体类Box,它能计算并输出立方体的体积和表面积。要求:

  • (1)包含成员变量m_a(立方体边长)。
  • (2)包含函数SetA(double a)(设置立方体边长)、GetVolume()(计算体积)、GetArea()(计算表面积)。
  • (3)包含函数Display(),用来输出计算的结果。
  • (4)设计测试用主函数main(),用来测试Box类。

2.2 解题思路:

  • 1、 构建Box类。
  • 2、 分析Box类内的方法分别是做什么用的,成员变量需要什么样的数据结构来存储。
  • 3、 编写程序并进行调试。

2.3 代码及注释:

#include<iostream>
using namespace std;

class Box {
public:
	//SetA(double a)(设置立方体边长)
	void SetA(double a) {
		m_a = a;
	}

	//GetVolume()(计算体积)
	double GetVolume() {
		return m_a * m_a * m_a;
	}

	//GetArea()(计算表面积)
	double GetArea() {
		return m_a * m_a * 6;
	}

	//函数Display(),用来输出计算的结果。
	void Display() {
		cout << "Volume: " << GetVolume() << endl;
		cout << "Area: " << GetArea() << endl;
	}
	//立方体边长

private:
	double m_a;
};


int main() {
	Box box;
	//将box的边长设置成2.5
	box.SetA(2.5);
	//展示体积和表面积的计算结果
	box.Display();
	return 1;
}

2.4 程序运行结果分析:

我们将立方体的边长设置成2.5,计算其体积和表面积并展示,结果如下:

Volume: 15.625
Area: 37.5
请按任意键继续. . .

因此,程序执行正确。

习题3

3.1 题目:

设计一个Rectangle类。要求:

  • (1)包含两个成员变量m_length和m_width,其默认值为1。
  • (2)包含成员函数Perimeter()计算长方形的周长,Area()计算长方形面积。
  • (3)包含成员函数SetWidth()和GetWidth()用来设置和得到m_width的值,SetLength()和GetLength()用来设置和得到m_length的值。Set…()函数应验证m_length和m_width均为0.0到20.0之间的浮点数。
  • (4)编写主函数,测试Rectangle类。

3.2 解题思路:

  • 1、 构建Rectangle类。
  • 2、 编写Rectangle类内的成员变量和成员函数,其中成员变量为private,成员函数为public。
  • 3、 编写程序并进行调试。

3.3 代码及注释:

#include<iostream>
using namespace std;

class Rectangle {
public:
	//Perimeter()计算长方形的周长
	double Perimeter() { return 2 * (m_length + m_width); }
	//Area()计算长方形面积
	double Area() { return m_length * m_width; }

	//SetWidth()和GetWidth()用来设置和得到m_width的值
	void SetWidth(double w) { m_width = w; }
	double GetWidth() { return m_width; }

	//SetLength()和GetLength()用来设置和得到m_length的值
	void SetLength(double l) { m_length = l; }
	double GetLength() { return m_length; }

	//Set_()函数应验证m_length和m_width均为0.0到20.0之间的浮点数。
	bool Set_() {
		bool n = 1;
		if (0 > m_length || 20 < m_length) {
			cout << "length is not in 0.0 - 20.0" << endl;
			n = 0;
		}
		if (0 > m_width || 20 < m_width) {
			cout << "width is not in 0.0 - 20.0" << endl;
			n = 0;
		}
		if (n)
			cout << "length and width are both in 0.0 - 20.0" << endl;
		return n;
	}
private:
	//两个成员变量m_length和m_width,其默认值为1
	double m_length = 1;
	double m_width = 1;
};

int main() {
	Rectangle rec;
	cout << "Length : " << rec.GetLength() << "    " << "Width : " << rec.GetWidth() << endl;
	rec.Set_();
	cout << endl << endl;

	rec.SetLength(5.2);
	rec.SetWidth(4);
	cout << "Length : " << rec.GetLength() << "    " << "Width : " << rec.GetWidth() << endl;
	rec.Set_();
	cout << endl << endl;

	rec.SetWidth(25);
	cout << "Length : " << rec.GetLength() << "    " << "Width : " << rec.GetWidth() << endl;
	rec.Set_();
	cout << endl << endl;

	return 1;
}

3.4 程序运行结果分析:

我们设置不同的值对其进行调试,其中:

  • 第一组为默认值。
  • 第二组为设置值且没有超出范围。
  • 第三组为设置值且超出范围。

结果如下:

Length : 1    Width : 1
length and width are both in 0.0 - 20.0


Length : 5.2    Width : 4
length and width are both in 0.0 - 20.0


Length : 5.2    Width : 25
width is not in 0.0 - 20.0

验证三组测试实验表明,程序执行正确。

习题4

4.1 题目:

编写一个程序,在已设置好若干个用户名/口令后,通过输入用户名,查找对应的口令,连续执行这一过程直到用户输入结束标记“end”为止。要求:

  • (1)设计一个User类,成员变量包含用户名和口令;另有一个无参构造函数和SetName()、SetPass()、GetName()、GetPass()四个成员函数,用于设置和获取用户名和口令,并根据需要编写析构函数。
  • (2)在主函数中设计一个对象数组,当用户输入一个用户名后,在对象数组中查找,找到后输出对应的口令,找不到时输出相应的提示信息。

4.2 解题思路:

  • 1、创建User类。
  • 2、将成员变量account和password设置成char*类型。
  • 3、初始时利用new运算符动态分配内存。
  • 4、析构函数利用delete删除内存。
  • 5、利用库函数strcpm函数进行字符串比较。
  • 6、利用库函数strcpy_s实现字符串拷贝。
  • 7、主函数内设置标签label判断是否存在用户名。

4.3 代码及注释:

#include<iostream>
#include <cstring>
using namespace std;


class User {
public:
	//无参构造函数
	User() {
		account = NULL;
		password = NULL;
	};
	//SetName()、SetPass()、GetName()、GetPass()四个成员函数
	//用于设置和获取用户名和口令
	void SetName(char* name) {
		account = new char[strlen(name) + 5];
		strcpy_s(account, strlen(name) + 1, name);
	}
	void SetPass(char* pass) {
		password = new char[strlen(pass) + 1];
		strcpy_s(password, strlen(pass) + 1, pass);
	}
	char* GetName() { return account; }
	char* GetPass() { return password; }
	//析构函数
	~User()
	{
			delete account;
			delete password;
	}
private:
	//成员变量
	char* account;
	char* password;
};

int main() {
	//设置初始用户名和密码
	User users[5];
	users[0].SetName("Jack");
	users[0].SetPass("jack.password");
	users[1].SetName("Mike");
	users[1].SetPass("mike.password");
	users[2].SetName("Micheal");
	users[2].SetPass("micheal.password");
	users[3].SetName("Rose");
	users[3].SetPass("rose.password");
	users[4].SetName("Eve");
	users[4].SetPass("eve.password");

	//循环搜索口令
	while (true) {
		cout << "Account : ";
		char *name = new char[100];
		//输入用户名
		cin >> name;
		//判断是否跳出
		if (strcmp(name, "end") == 0)
			break;
		//设立标签label判断用户是否存在
		bool label = false;
		for (int i = 0;i < 5;i++) {
			if (strcmp(name, users[i].GetName()) == 0) {
				//如果用户存在,输出口令
				cout << "Password : " << users[i].GetPass() << endl << endl;
				label = true;
			}
		}
		//如果用户不存在,输出提示
		if (label == false) {
			cout << "Error : " << "No account named " << name << endl << endl;
		}
		delete name;
	}
	
	return 1;
}

4.4 程序运行结果分析:

我们初始时设置好5组用户数据,当用户名输入正确时则输出口令,用户名错误时则给出提示,当输入end时结束,做以下操作:

Account : Jack
Password : jack.password

Account : jack
Error : No account named jack

Account : Rose
Password : rose.password

Account : end
请按任意键继续. . .

因此,程序执行正确。

习题5

5.1 题目:

编写一个Person类,包括:

  • 1、普通数据成员:姓名,性别,年龄。
  • 2、三个构造函数:无参数构造函数,有参数构造函数(参数:姓名的指针,年龄,性别),拷贝构造函数。
  • 3、析构函数,输出人员信息函数print()。

编写main()函数,分别调用三种构造函数,创建三个对象P1、P2、P3,其中P3的创建是用P2通过深拷贝复制得到的。

5.2 解题思路:

  • 1、创建Person类。
  • 2、创建不同类型的构造函数。
  • 3、分别调用不同的构造函数进行验证。

5.3 代码及注释:

#include<iostream>
#include <cstring>
using namespace std;


class Person {
public:
	//无参数构造函数
	Person() {
		char* name = NULL;
		sex = 0;
		age = 0;
		cout << "已使用无参数构造函数。" << endl;
	}
	//有参数构造函数(参数:姓名的指针,年龄,性别
	Person(char* n, int s, int a) {
		char* p = new char[strlen(n) + 1];
		name = p;
		strcpy_s(name, strlen(n) + 1, n);
		sex = s;
		age = a;
		cout << "已使用有参数构造函数。" << endl;
	}
	//拷贝构造函数
	Person(const Person &c) {
		char* p = new char[strlen(c.name) + 1];
		name = p;
		strcpy_s(name, strlen(c.name) + 1, c.name);
		sex = c.sex;
		age = c.age;
		cout << "已使用拷贝构造函数。" << endl;
	}
	//手动设置信息
	void Set(char* n, int s, int a) {
		delete name;
		char* p = new char[strlen(n) + 1];
		name = p;
		strcpy_s(name, strlen(n) + 1, n);
		sex = s;
		age = a;
	}
	//输出人员信息函数
	void print() {
		cout << "Information : " << endl;
		char* d = "male";
		if (sex == 1)
			d = "female";
		cout << "Name : " << name << "\tSex : " << d << "\tAge : " << age << endl << endl;
	}
	//析构函数
	~Person() { delete name; }

private:
	//普通数据成员:姓名,性别,年龄。
	char* name;
	//0表示男,1表示女
	int sex;
	int age;
};

int main() {
	Person p1;
	p1.Set("Rose", 1, 18);
	p1.print();

	Person p2("Jack", 0, 20);
	p2.print();

	Person p3 = p2;
	p3.print();

	return 1;
}

5.4 程序运行结果分析:

我们创建三个Person对象进行实验:

  • 第一组是利用无参构造函数创建,用set函数进行赋值操作。
  • 第二组是利用有参构造函数创建。
  • 第三组是利用拷贝构造函数创建。

实验结果如下:

已使用无参数构造函数。
Information :
Name : Rose     Sex : female    Age : 18

已使用有参数构造函数。
Information :
Name : Jack     Sex : male      Age : 20

已使用拷贝构造函数。
Information :
Name : Jack     Sex : male      Age : 20

请按任意键继续. . .

由实验结果可知:程序执行正确。

习题6

6.1 题目:

编写一个程序,输入N个学生数据,包括学号、姓名、成绩,输出这些学生数据并计算平均分。要求:

  • (1)设计一个学生类Stud,除了包括学号、姓名和成绩数据成员外,有两个静态变量分别存放总分和人数。
  • (2)有两个普通成员函数SetData()和Disp(),分别用于给数据成员赋值和输出数据成员的值。另有一个静态成员函数Avg(),它用于计算平均分。
  • (3)在main()函数中定义一个对象数组用于存储输入的学生数据。

6.2 解题思路:

  • 1、建立Stud类。
  • 2、创建静态成员变量。
  • 3、创建题目要求的函数。
  • 4、输入数据进行验证。

6.3 代码及注释:

#include<iostream>
#include <cstring>
using namespace std;

class Stud {
public:
	//静态变量存放总分和人数
	static double sum_score;
	static int num;

	//有两个普通成员函数SetData()和Disp(),分别用于给数据成员赋值和输出数据成员的值。
	void SetData(int i, char *n, double s)
	{
		id = i;
		name = new char[strlen(n) + 1];
		strcpy_s(name, strlen(n) + 1, n);
		score = s;
		sum_score += score;
		num += 1;
	}
	void Disp()
	{
		cout << "id:" << id << "\tname:" << name << "\tscore:" << score << endl;
	}

	//静态成员函数Avg(),它用于计算平均分
	static double Avg() { return sum_score / num; }
private:
	//学号、姓名、成绩
	int id;
	char * name;
	double score;
};

//初始化静态成员变量
double Stud::sum_score = 0;
int Stud::num = 0;

int main() {
	int ids[] = { 1,2,3,4,5 };
	char *stunames[] = { "Rose","Mike","Eve","Micheal","Jack" };
	double scores[] = { 95,84,88,64,100 };
	Stud stud[5];

	for (int i = 0;i < 5;i++) 
		stud[i].SetData(ids[i], stunames[i], scores[i]);

	for (int i = 0;i < 5;i++)
		stud[i].Disp();
	
	cout << "\tsum_score:" << stud[0].sum_score << "\tavg:" << stud[0].Avg() << endl;
	return 1;
}

6.4 程序运行结果分析:

我们输入五组数据并展示,结果如下:

id:1    name:Rose       score:95
id:2    name:Mike       score:84
id:3    name:Eve        score:88
id:4    name:Micheal    score:64
id:5    name:Jack       score:100
        sum_score:431   avg:86.2
请按任意键继续. . .

由结果得,程序执行正确。

习题7

7.1 题目:

有一个学生类Student,包括学生姓名、成绩,要求:

  • (1)设计一个友元函数Compare(),比较两个学生成绩的高低。
  • (2)在main()函数中定义一个对象数组用于存储输入学生的数据,并求出最高分和最低分的学生。

7.2 解题思路:

  • 1、构建Student类。
  • 2、编写必要的成员函数。
  • 3、编写Compare函数进行两个学生成绩的比较,1表示大于,0表示等于,-1表示小于。
  • 4、编写程序并进行调试。

7.3 代码及注释:

#include<iostream>
#include <cstring>
using namespace std;


class Student {
public:
	//友元函数Compare(),比较两个学生成绩的高低
	friend int Compare(Student* a, Student* b);

	//用于设置学生信息
	void Set(char* n, double s) {
		name = new char[strlen(n) + 1];
		strcpy_s(name, strlen(n) + 1, n);
		score = s;
	}

	//用于获取学生信息
	double GetScore() { return score; }
	char* GetName() { return name; }

	//显示学生信息
	void Display() {
		cout << "Name:" << name << "\tScore:" << score << endl;
	}

	//析构函数
	~Student()
	{
		delete name;
	}
private:
	char* name;
	double score;
};


//1表示大于,0表示等于,-1表示小于
int Compare(Student* a, Student* b) {
	if (a->GetScore() > b->GetScore())
		return 1;
	else if (a->GetScore() == b->GetScore())
		return 0;
	else
		return -1;
}

int main() {
	Student* min, *max;
	Student studs[5];
	char *stunames[] = { "Rose","Mike","Eve","Micheal","Jack" };
	double scores[] = { 95,84,88,64,100 };

	for (int i = 0;i < 5;i++) {
		studs[i].Set(stunames[i], scores[i]);
		studs[i].Display();
	}

	min = &studs[0];
	max = &studs[0];
	for (int i = 1;i < 5;i++) {
		Student* j = &studs[i];
		if (Compare(min, j) == 1)
			min = j;
		if (Compare(max, j) == -1)
			max = j;
	}
	cout << "The worst student : " << min->GetName() << endl;
	cout << "The best student : " << max->GetName() << endl;


	return 1;
}

7.4 程序运行结果分析:

我们创建对象数组设置5组初始的学生信息,并求出最低分和最高分的同学:

Name:Rose       Score:95
Name:Mike       Score:84
Name:Eve        Score:88
Name:Micheal    Score:64
Name:Jack       Score:100
The worst student : Micheal
The best student : Jack
请按任意键继续. . .

因此,程序执行正确。

习题8

8.1 题目:

设计一个Rational类,进行带分数的运算。要求:

  • (1)包含两个整数成员变量表示分子和分母。
  • (2)包含一个对所声明对象初始化的构造函数。不提供参数时,构造函数应提供默认值。分数存放成简化形式,例如分数“2/4”应在对象中存放成分子1和分母2的形式。
  • (3)对下列情况提供public成员函数:

a)两个Rational值相加,结果保存成简化形式。

b)两个Rational值相减,结果保存成简化形式。

c)两个Rational值相乘,结果保存成简化形式。

d)两个Rational值相除,结果保存成简化形式。

e)按a/b形式打印Rational值,其中a为分子,b为分母。

  • (4)编写主函数,测试Rational类。
  • (5)将上述成员函数改为运算符重载的形式,分别作为成员函数和友元函数实现上述功能。

8.2 解题思路:

  • 1、 构建Rational类。
  • 2、 编写Rational类内的成员变量和成员函数。
  • 3、 用运算符重载、成员函数、友元函数分别实现加减乘除的操作。
  • 4、 编写程序并进行调试。

8.3 代码及注释:

#include<iostream>
#include<algorithm>
using namespace std;


class Rational {
public:
	Rational() {
		mol = 0;
		den = 1;
	}
	Rational(int a, int b) {
		mol = a;
		den = b;
		Simplify();
	}

	

	//成员函数形式
	Rational Addition(Rational b) {
		Rational c;
		c.den = this->den * b.den;
		c.mol = (this->den * b.mol) + (this->mol * b.den);
		c.Simplify();
		return c;
	}
	Rational Subtract(Rational b) {
		Rational c;
		c.den = this->den * b.den;
		c.mol = (this->mol * b.den) - (this->den * b.mol);
		c.Simplify();
		return c;
	}
	Rational Multiply(Rational b) {
		Rational c;
		c.den = this->den * b.den;
		c.mol = this->mol * b.mol;
		c.Simplify();
		return c;
	}
	Rational Division(Rational b) {
		Rational c;
		c.den = this->den * b.mol;
		c.mol = this->mol * b.den;
		c.Simplify();
		return c;
	}

	//成员函数运算符重载形式
	Rational operator+(const Rational& b)
	{
		Rational c;
		c.den = this->den * b.den;
		c.mol = (this->den * b.mol) + (this->mol * b.den);
		c.Simplify();
		return c;
	}
	Rational operator-(const Rational& b)
	{
		Rational c;
		c.den = this->den * b.den;
		c.mol = (this->mol * b.den) - (this->den * b.mol);
		c.Simplify();
		return c;
	}
	Rational operator*(const Rational& b)
	{
		Rational c;
		c.den = this->den * b.den;
		c.mol = this->mol * b.mol;
		c.Simplify();
		return c;
	}
	Rational operator/(const Rational& b)
	{
		Rational c;
		c.den = this->den * b.mol;
		c.mol = this->mol * b.den;
		c.Simplify();
		return c;
	}


	//友元函数运算符重载形式
	/*
	friend Rational operator+(Rational a, Rational b);
	friend Rational operator-(Rational a, Rational b);
	friend Rational operator*(Rational a, Rational b);
	friend Rational operator/(Rational a, Rational b);
	*/

	//打印结果
	void Print() {
		cout << mol << "/" << den << endl;
	}

	//分子分母化简
	void Simplify();
private:
	//mol表示分子,den表示分母
	int mol;
	int den;
};

void Rational::Simplify() {
	bool label = 1;
	while (label) {
		bool tag = 1;
		for (int i = 2;i <= min(mol, den);i++) {
			if (double(den) / i - den / i == 0 && double(mol) / i - mol / i == 0) {
				tag = 0;
				den = den / i;
				mol = mol / i;
				break;
			}
		}
		if (tag)
			label = 0;
	}
}

/*
Rational operator+(Rational a, Rational b) {
Rational c;
c.den = a.den * b.den;
c.mol = (a.den * b.mol) + (a.mol * b.den);
c.Simplify();
return c;
}
Rational operator-(Rational a, Rational b) {
Rational c;
c.den = a.den * b.den;
c.mol = (a.mol * b.den) - (a.den * b.mol);
c.Simplify();
return c;
}
Rational operator*(Rational a, Rational b) {
Rational c;
c.den = a.den * b.den;
c.mol = a.mol * b.mol;
c.Simplify();
return c;
}
Rational operator/(Rational a, Rational b) {
Rational c;
c.den = a.den * b.mol;
c.mol = a.mol * b.den;
c.Simplify();
return c;
}
*/

int main() {
	Rational k1(60, 120), k2(34, 340);
	cout << "k1 : ";
	k1.Print();
	cout << "k2 : ";
	k2.Print();
	cout << endl;

	Rational k3;
	cout << "成员函数形式:" << endl;
	k3 = k1.Addition(k2);
	cout << "Addition : ";
	k3.Print();
	k3 = k1.Subtract(k2);
	cout << "Subtract : ";
	k3.Print();
	k3 = k1.Multiply(k2);
	cout << "Multiply : ";
	k3.Print();
	k3 = k1.Division(k2);
	cout << "Division : ";
	k3.Print();
	cout << endl;

	cout << "成员函数运算符重载形式:" << endl;
	k3 = k1 + k2;
	cout << "Addition : ";
	k3.Print();
	k3 = k1 - k2;
	cout << "Subtract : ";
	k3.Print();
	k3 = k1 * k2;
	cout << "Multiply : ";
	k3.Print();
	k3 = k1 / k2;
	cout << "Division : ";
	k3.Print();
	cout << endl;
	
	/*
	cout << "友元函数运算符重载形式:" << endl;
	k3 = k1 + k2;
	cout << "Addition : ";
	k3.Print();
	k3 = k1 - k2;
	cout << "Subtract : ";
	k3.Print();
	k3 = k1 * k2;
	cout << "Multiply : ";
	k3.Print();
	k3 = k1 / k2;
	cout << "Division : ";
	k3.Print();
	cout << endl;
	*/
	
	return 1;
}

8.4 程序运行结果分析:

我们设置值对其进行调试,其中:

  • 我们设置两个数k1和k2。
  • 分别用成员函数形式检验加减乘除。
  • 分别用成员函数参数重载形式检验加减乘除。
  • 分别用友元函数参数重载形式检验加减乘除。
  • (参数重载和友元函数)

结果如下:

k1 : 1/2
k2 : 1/10

成员函数形式:
Addition : 3/5
Subtract : 2/5
Multiply : 1/20
Division : 5/1

成员函数运算符重载形式:
Addition : 3/5
Subtract : 2/5
Multiply : 1/20
Division : 5/1

请按任意键继续. . .
k1 : 1/2
k2 : 1/10

成员函数形式:
Addition : 3/5
Subtract : 2/5
Multiply : 1/20
Division : 5/1

友元函数运算符重载形式:
Addition : 3/5
Subtract : 2/5
Multiply : 1/20
Division : 5/1

请按任意键继续. . .

验证测试实验表明,程序执行正确。

  • 47
    点赞
  • 223
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值