第十一章编程练习

1.修改程序清单11.15,使之将一系列连续的随机漫步者位置写入到文件中。对于每个位置,用步号进行标记。另外,让该程序将初始条件(目标距离和步长)以及结果小结写入到该文件中。该文件的内容与下面类似:
Target Distance: 100, Step size: 20
0: (x, y) = (0, 0)
1: (x, y) = (-11.4715, 16.383)
2: (x, y) = (-8.68807, -3.422232)

26: (x,y) = (42.2919, -78.2594)
27: (x,y) = (58.6749, -89.7309)
After 27 steps, the subject has the following location:
(x,y) = (58.6749, -89.7309)
or
(m,a) = (107.212, -56.8194)
Average outward distance per step = 3.97081

实现:
vect.h

#pragma once
#include <iostream>

namespace VECTOR
{
	class Vector
	{
	public:
		enum Mode{RECT, POL};//RECT for rectangular, POL for polar modes
	private:
		double x;//horizontal value
		double y;//vertical value
		double mag;//length of vector
		double ang;//direction of vector in degrees
		Mode mode;
		//private methods for setting values
		void set_mag();
		void set_ang();
		void set_x();
		void set_y();
	public:
		Vector();
		Vector(double n1, double n2, Mode form = RECT);
		void reset(double n1, double n2, Mode form = RECT);
		~Vector();
		double xval() const { return x; }
		double yval() const { return y; }
		double magval() const { return mag; }
		double angval() const { return ang; }
		void polar_mode();//set mode to POL
		void rect_mode();//set mode to RECT
		//operator overloading
		Vector operator+(const Vector& b) const;
		Vector operator-(const Vector& b)const;
		Vector operator-()const;
		Vector operator*(double n) const;
		//friends
		friend Vector operator* (double n, const Vector& a);
		friend std::ostream& 
			operator<< (std::ostream& os, const Vector& v);
		
	};
}

vect.cpp

#include "vect.h"
using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;
using std::cout;

namespace VECTOR
{
	//compute degrees in one radian
	const double Rad_to_Deg = 45.0 / atan(1.0);//about 57.2957795130823
	//private methods, calculating magnitude from x and y
	void Vector::set_mag()
	{
		mag = sqrt(x * x + y * y);
	}

	void Vector::set_ang()
	{
		if (x == 0.0 && y == 0.0)
		{
			ang = 0.0;
		}
		else
		{
			ang = atan2(y, x);
		}
	}
	//set x from polar coordinate
	void Vector::set_x()
	{
		x = mag * cos(ang);
	}
	//set y from polar coordinate
	void Vector::set_y()
	{
		y = mag * sin(ang);
	}
	//public methods 
	Vector::Vector()//default constructor
	{
		x = y = mag = ang = 0.0;
		mode = RECT;
	}
	//constructor vector from rectangular coordinates if form is r
	//(the default) or else from polar coordinate if form is p
	Vector::Vector(double n1, double n2, Mode form)
	{
		mode = form;
		if (form == RECT)
		{
			x = n1;
			y = n2;
			set_mag();
			set_ang();
		}
		else if(form == POL)
		{
			mag = n1;
			ang = n2 / Rad_to_Deg;
			set_x();
			set_y();
		}
		else
		{
			cout << "Incorrect 3rd argument to Vector()--";
			cout << "vector set to 0\n";
			x = y = mag = ang = 0.0;
			mode = RECT;
		}
	}
	//reset vector from rectangular coordinates if form is RECT
	//or else from polar coordinates if form is POL
	void Vector::reset(double n1, double n2, Mode form)
	{
		mode = form;
		if (form == RECT)
		{
			x = n1;
			y = n2;
			set_mag();
			set_ang();
		}
		else if (form == POL)
		{
			mag = n1;
			ang = n2 / Rad_to_Deg;
			set_x();
			set_y();
		}
		else
		{
			cout << "Incorrect 3rd argument to Vector()--";
			cout << "vector set to 0\n";
			x = y = mag = ang = 0.0;
			mode = RECT;
		}
	}
	//dectructor
	Vector::~Vector()
	{
	}
	//set to polar mode
	void Vector::polar_mode()
	{
		mode = POL;
	}
	//set to rectangular mode
	void Vector::rect_mode()
	{
		mode = RECT;
	}
	//operator overloading
	//add two Vectors
	Vector Vector::operator+(const Vector& b) const
	{
		return Vector(x + b.x, y + b.y);
	}
	//subtract Vector b from a
	Vector Vector::operator-(const Vector& b) const
	{
		return Vector(x - b.x, y - b.y);
	}
	//reverse sign of Vector
	Vector Vector::operator-() const
	{
		return Vector(-x, -y);
	}
	//multiply vector by n
	Vector Vector::operator*(double n) const
	{
		return Vector(n * x, n * y);
	}
	//friend methods
	//multiply n by Vector a
	Vector operator*(double n, const Vector& a)
	{
		return a * n;
	}
	//display rectangular coordinates if mode is RECT, 
	//else display polar coordinates if mode is POL
	std::ostream& operator<<(std::ostream& os, const Vector& v)
	{
		if (v.mode == Vector::RECT)
		{
			os << "(x,y) = (" << v.x << "," << v.y << ")";
		}
		else if (v.mode == Vector::POL)
		{
			os << "(m,a) = (" << v.mag << "," << v.ang * Rad_to_Deg << ")";
		}
		else
		{
			os << "Vector object mode is invalid";
		}
		return os;
	}
}

main.cpp

#include <iostream>

#include <fstream>//ofstream
#include "vect.h"
int main(void)
{
	using VECTOR::Vector;
	using std::ofstream;
	
	double target;
	double dstep;
	srand(time(0));
	double direction;
	Vector step;
	Vector result(0.0, 0.0);
	unsigned long steps = 0;

	ofstream fout;
	fout.open("randwalk.txt");//当前路径下

	cout << "Enter target distance(q to quit):";
	while (cin >> target)
	{
		cout << "Enter step length:";
		if (!(cin >> dstep))
		{
			break;
		}

		fout << "Target Distance: " << target << ", Step Size: " << dstep;

		while (result.magval() < target)
		{
			fout << steps << ":(x, y) = " << result << endl;

			direction = rand() % 360;
			step.reset(dstep, direction, Vector::POL);
			result = result + step;
			steps++;
		}

		cout << "After " << steps << " steps, the subject has the following location:\n";
		cout << result << endl;

		fout << "After " << steps << " steps, the subject has the following location:\n";
		fout << result << endl;

		result.polar_mode();

		cout << " or\n" << result << endl;
		fout << " or\n" << result << endl;

		cout << "Average outward distance per step = " << result.magval() / steps << endl;
		fout << "Average outward distance per step = " << result.magval() / steps << endl;

		steps = 0;
		result.reset(0.0, 0.0);
		cout << "Enter target distance(q to quit):";
	}
	cout << "Bye!" << endl;
	cin.clear();
	while (cin.get() != '\n')
	{
		continue;
	}

	return 0;
}

2.对Vector类的头文件(程序清单11.13)和实现文件(程序清单11.14)进行修改,使其不再存储矢量的长度和角度,而是在magval()和angval()被调用时计算它们。
应保留公有接口不变(公有方法及其参数不变),但对私有部分(包括一些私有方法)和方法实现进行修改。然后,使用程序清单11.15对修改后的版本进行测试,结果应该与以前相同,因为Vector类的公有接口与原来相同。
实现:
vect.h

namespace VECTOR
{
	class Vector
	{
	public:
		enum Mode { RECT, POL };//RECT for rectangular, POL for polar modes
	private:
		double x;//horizontal value
		double y;//vertical value
		Mode mode;
		//private methods for setting values
		void set_x(double mag, double ang);
		void set_y(double mag, double ang);
	public:
		Vector();
		Vector(double n1, double n2, Mode form = RECT);
		void reset(double n1, double n2, Mode form = RECT);
		~Vector();
		double xval() const { return x; }
		double yval() const { return y; }
		double magval() const;
		double angval() const;
		void polar_mode();//set mode to POL
		void rect_mode();//set mode to RECT
		//operator overloading
		Vector operator+(const Vector& b) const;
		Vector operator-(const Vector& b)const;
		Vector operator-()const;
		Vector operator*(double n) const;
		//friends
		friend Vector operator* (double n, const Vector& a);
		friend std::ostream&
			operator<< (std::ostream& os, const Vector& v);

	};
}

vect.cpp

#include "vect.h"

namespace VECTOR
{
	//compute degrees in one radian
	const double Rad_to_Deg = 45.0 / atan(1.0);//about 57.2957795130823
	//private methods, calculating magnitude from x and y

	//set x from polar coordinate
	void Vector::set_x(double mag, double ang)
	{
		x = mag * cos(ang);
	}
	//set y from polar coordinate
	void Vector::set_y(double mag, double ang)
	{
		y = mag * sin(ang);
	}
	double Vector::magval() const
	{
		return sqrt(x * x + y * y);
	}
	double Vector::angval() const
	{
		if (x == 0.0 && y == 0.0)
		{
			return 0.0;
		}
		else
		{
			return atan2(y, x);
		}
	}
	//public methods 
	Vector::Vector()//default constructor
	{
		x = y = 0.0;
		mode = RECT;
	}
	//constructor vector from rectangular coordinates if form is r
	//(the default) or else from polar coordinate if form is p
	Vector::Vector(double n1, double n2, Mode form)
	{
		mode = form;
		if (form == RECT)
		{
			x = n1;
			y = n2;
		}
		else if (form == POL)
		{
			set_x(n1, n2 / Rad_to_Deg);
			set_y(n1, n2 / Rad_to_Deg);
		}
		else
		{
			cout << "Incorrect 3rd argument to Vector()--";
			cout << "vector set to 0\n";
			x = y = 0.0;
			mode = RECT;
		}
	}
	//reset vector from rectangular coordinates if form is RECT
	//or else from polar coordinates if form is POL
	void Vector::reset(double n1, double n2, Mode form)
	{
		mode = form;
		if (form == RECT)
		{
			x = n1;
			y = n2;
		}
		else if (form == POL)
		{
			set_x(n1, n2 / Rad_to_Deg);
			set_y(n1, n2 / Rad_to_Deg);
		}
		else
		{
			cout << "Incorrect 3rd argument to Vector()--";
			cout << "vector set to 0\n";
			x = y = 0.0;
			mode = RECT;
		}
	}
	//dectructor
	Vector::~Vector()
	{
	}
	//set to polar mode
	void Vector::polar_mode()
	{
		mode = POL;
	}
	//set to rectangular mode
	void Vector::rect_mode()
	{
		mode = RECT;
	}
	//operator overloading
	//add two Vectors
	Vector Vector::operator+(const Vector& b) const
	{
		return Vector(x + b.x, y + b.y);
	}
	//subtract Vector b from a
	Vector Vector::operator-(const Vector& b) const
	{
		return Vector(x - b.x, y - b.y);
	}
	//reverse sign of Vector
	Vector Vector::operator-() const
	{
		return Vector(-x, -y);
	}
	//multiply vector by n
	Vector Vector::operator*(double n) const
	{
		return Vector(n * x, n * y);
	}
	//friend methods
	//multiply n by Vector a
	Vector operator*(double n, const Vector& a)
	{
		return a * n;
	}
	//display rectangular coordinates if mode is RECT, 
	//else display polar coordinates if mode is POL
	std::ostream& operator<<(std::ostream& os, const Vector& v)
	{
		if (v.mode == Vector::RECT)
		{
			os << "(x,y) = (" << v.x << "," << v.y << ")";
		}
		else if (v.mode == Vector::POL)
		{
			os << "(m,a) = (" << v.magval() << "," << v.angval() * Rad_to_Deg << ")";
		}
		else
		{
			os << "Vector object mode is invalid";
		}
		return os;
	}
}

main.cpp

#include "vect.h"

int main(void)
{
	using VECTOR::Vector;
	srand(time(0));
	double direction;
	Vector step;
	Vector result(0.0, 0.0);
	unsigned long steps = 0;
	double target;
	double dstep;
	cout << "Enter target distance(q to quit):";
	while (cin >> target)
	{
		cout << "Enter step length:";
		if (!(cin >> dstep))
		{
			break;
		}

		while (result.magval() < target)
		{
			direction = rand() % 360;//1至359
			step.reset(dstep, direction, Vector::POL);
			result = result + step;
			steps++;
		}
		cout << "After " << steps << " steps, the subject has the following location:\n";
		cout << result << endl;
		result.polar_mode();
		cout << " or\n" << result << endl;
		cout << "Average outward distance per step = " << result.magval() / steps << endl;
		steps = 0;
		result.reset(0.0, 0.0);
		cout << "Enter target distance(q to quit):";
	}
	cout << "Bye!" << endl;
	cin.clear();
	while (cin.get() != '\n')
	{
		continue;
	}
	return 0;
}

3.修改程序清单11.15,使之报告N次测试中的最高、最低和平均步数(其中N是用户输入的整数),而不是报告每次测试的结果。

#include "vect.h"

int main(void)
{
	using VECTOR::Vector;
	srand(time(NULL));
	double direction;
	Vector step;
	Vector result(0.0, 0.0);
	unsigned long steps = 0;
	double target;
	double dstep;
	unsigned int N;			//用户输入的次数
	unsigned int max = 0;	//最高步数
	unsigned int min = 0;	//最低步数
	unsigned int sum = 0;	//平均步数
	cout << "How many times do you want to try? :";
	cin >> N;
	cout << "Enter target distance:";
	cin >> target;

	cout << "Enter step length:";
	cin >> dstep;

	for (int i = 0; i < N; i++)
	{
		while (result.magval() < target)
		{
			direction = rand() % 360;//1至359
			step.reset(dstep, direction, Vector::POL);
			result = result + step;
			steps++;
		}

		max = (max > steps) ? max : steps;
		if (min == 0)//第一次运行时
		{
			min = max;
		}
		else
		{
			min = (min < steps) ? min : steps;
		}

		sum += steps;

		steps = 0;
		result.reset(0.0, 0.0);
	}
	cout << "Max steps:" << max << endl;
	cout << "Min steps:" << min << endl;
	cout << "Average steps:" << (double)sum / N << endl;
	cout << "Bye!" << endl;
	cin.clear();
	while (cin.get() != '\n')
	{
		continue;
	}
	return 0;
}

4.重新编写最后的Time类示例(程序清单11.10、程序清单11.11、程序清单11.12),使用友元函数来实现所有的重载运算符。
实现:
time.h

#pragma once

#include <iostream>

class Time
{
private:
	int hours;
	int minutes;
public:
	Time();
	Time(int h, int m = 0);
	void AddMin(int m);
	void AddHr(int h);
	void Reset(int h = 0, int m = 0);
	friend Time operator+(const Time& t1, const Time& t2);	//->友元
	friend Time operator-(const Time& t1, const Time& t2);	//->友元
	friend Time operator*(const Time& t1, double n);		//->友元
	friend Time operator*(double m, const Time& t) { return t * m; }//inline definition
	friend std::ostream& operator<< (std::ostream& os, const Time& t);

};

time.cpp

#include "time.h"

Time::Time()
{
	hours = minutes = 0;
}

Time::Time(int h, int m)
{
	hours = h;
	minutes = m;
}

void Time::AddMin(int m)
{
	minutes += m;
	hours += minutes / 60;
	minutes %= 60;
}

void Time::AddHr(int h)
{
	hours += h;
}

void Time::Reset(int h, int m)
{
	hours = h;
	minutes = m;
}

Time operator+(const Time& t1, const Time& t2)
{
	Time time;
	time.minutes = t1.minutes + t2.minutes;
	time.hours = t1.hours + t2.hours + time.minutes / 60;
	time.minutes = time.minutes % 60;
	return time;
}

Time operator-(const Time& t1, const Time& t2)
{
	Time diff;
	int total1, total2;
	total1 = t1.minutes + 60 * t1.hours ;
	total2 = t2.minutes + 60 * t2.hours;
	diff.hours = (total2 - total1) / 60;
	diff.minutes = (total2 - total1) % 60;
	return diff;
}

Time operator*(const Time& t1, double n)
{
	Time result;
	long totalminutes = t1.hours * n * 60 + t1.minutes * n;
	result.hours = totalminutes / 60;	//商
	result.minutes = totalminutes % 60;	//余数
	return result;
}

std::ostream& operator<<(std::ostream& os, const Time& t)
{
	os << t.hours << " hours, " << t.minutes << " minutes";
	return os;
}

5.重新编写Stonewt类(程序清单11.16和程序清单11.17),使它有一个状态成员,由该成员控制对象应转换为英石格式、整数磅格式还是浮点磅格式。重载<<运算符,使用它来替换show_stn()和show_lbs()方法。重载加法、减法和乘法运算符,以便可以对Stonewt值进行加、减、乘运算。编写一个使用所有类方法和友元的小程序,来测试这个类。
实现:
stonewt.h

#pragma once
#include <iostream>
using namespace std;
class Stonewt
{
public:
	enum Type{STONE, POUNDS, FLOATPOUNDS};
private:
	enum { Lbs_per_stn = 14 };		//pounds per stone
	int stone;						//whole stones
	double pds_left;				//fractional pounds
	double pounds;					//entire weight in pounds
	Type type;
public:
	Stonewt(double lbs);			//constructor for double pounds
	Stonewt(int stn, double lbs);	//constructor for stone, lbs
	Stonewt();						//default constructor
	~Stonewt();
	void SetType(Type m);
	Stonewt operator+(const Stonewt&s)const;
	Stonewt operator-(const Stonewt& s)const;
	Stonewt operator*(double n)const;
	friend ostream& operator<< (ostream& os, const Stonewt& s);//cout << stone; 
};

stonewt.cpp

#include "stonewt.h"

Stonewt::Stonewt(double lbs)
{
	stone = int(lbs) / Lbs_per_stn;
	pds_left = int(lbs) % Lbs_per_stn + lbs - int(lbs);
	pounds = lbs;
}

Stonewt::Stonewt(int stn, double lbs)
{
	stone = stn;
	pds_left = lbs;
	pounds = stn * Lbs_per_stn + lbs;
}

Stonewt::Stonewt()
{
	stone = pounds = pds_left = 0;
}

Stonewt::~Stonewt()
{
}

void Stonewt::SetType(Type m)
{
	type = m;
}

Stonewt Stonewt::operator+(const Stonewt& s) const
{
	return Stonewt(pounds + s.pounds);
}

Stonewt Stonewt::operator-(const Stonewt& s) const
{
	return Stonewt(pounds - s.pounds);;
}

Stonewt Stonewt::operator*(double n) const
{
	return Stonewt(pounds * n);
}

ostream& operator<<(ostream& os, const Stonewt& s)
{
	if (s.type == Stonewt::STONE)
	{
		os << s.stone << " stone, " << s.pds_left << " pounds" << endl;
	}
	else if(s.type == Stonewt::POUNDS)
	{
		os << int(s.pounds) << " pounds" << endl;

	}
	else if (s.type == Stonewt::FLOATPOUNDS)
	{
		os << s.pounds << " pounds" << endl;
	}
	else
	{
		os << "Invalid type" << endl;
	}
	return os;
}

main.cpp

#include "stonewt.h"

int main(void)
{
	Stonewt incognito = 275;
	Stonewt wolfe(285.7);
	Stonewt taft(21, 8);
	incognito.SetType(Stonewt::POUNDS);
	cout << "incognito:" << incognito;
	wolfe.SetType(Stonewt::FLOATPOUNDS);
	cout << "wolfe:" << wolfe;
	taft.SetType(Stonewt::STONE);
	cout << "taft:" << taft;

	taft = incognito + wolfe;
	taft.SetType(Stonewt::STONE);
	cout << "incognito + wolfe = :" << taft;

	taft = wolfe - incognito;
	taft.SetType(Stonewt::FLOATPOUNDS);
	cout << "wolfe - incognito = :" << taft;

	incognito = incognito * 2;
	incognito.SetType(Stonewt::POUNDS);
	cout << "incognito * 2 = :" << incognito;
	
	return 0;
}

6.重新编写Stonewt类(程序清单11.16和程序清单11.17),重载全部6个关系运算符。运算符对pounds成员进行比较,并返回一个bool值。编写一个程序,它声明一个包含6个Stonewt对象的数组,并在数组声明中初始化前3个对象。然后使用循环来读取用于设置剩余3个数组元素的值。接着报告最小的元素、最大的元素以及大于或等于11英石的元素的数量(最简单的方式是创建一个Stonewt对象,并将其初始化为11英石,然后将其同其他对象进行比较。)
实现:
stonewt.h

#pragma once
#include <iostream>
using namespace std;

class Stonewt
{
private:
	enum { Lbs_per_stn = 14 };		//pounds per stone
	int stone;						//whole stones
	double pds_left;				//fractional pounds
	double pounds;					//entire weight in pounds
public:
	Stonewt(double lbs);			//constructor for double pounds
	Stonewt(int stn, double lbs);	//constructor for stone, lbs
	Stonewt();						//default constructor
	~Stonewt();

	bool operator<(const Stonewt& s)const;
	bool operator<=(const Stonewt& s)const;
	bool operator>(const Stonewt& s)const;
	bool operator>=(const Stonewt& s)const;
	bool operator==(const Stonewt& s)const;
	bool operator!=(const Stonewt& s)const;

	void show_lbs()const;			//show weight in pounds format
	void show_std()const;			//show weight in stone format
};

stonewt.cpp

#include "stonewt.h"

Stonewt::Stonewt(double lbs)
{
	stone = int(lbs) / Lbs_per_stn;
	pds_left = int(lbs) % Lbs_per_stn + lbs - int(lbs);
	pounds = lbs;
}

Stonewt::Stonewt(int stn, double lbs)
{
	stone = stn;
	pds_left = lbs;
	pounds = stn * Lbs_per_stn + lbs;
}

Stonewt::Stonewt()
{
	stone = pounds = pds_left = 0;
}

Stonewt::~Stonewt()
{
}

bool Stonewt::operator<(const Stonewt& s) const
{
	return pounds < s.pounds;
}

bool Stonewt::operator<=(const Stonewt& s) const
{

	return pounds <= s.pounds;
}

bool Stonewt::operator>(const Stonewt& s) const
{
	return pounds > s.pounds;
}

bool Stonewt::operator>=(const Stonewt& s) const
{
	return pounds >= s.pounds;
}

bool Stonewt::operator==(const Stonewt& s) const
{
	return pounds == s.pounds;
}

bool Stonewt::operator!=(const Stonewt& s) const
{
	return pounds != s.pounds;

}

void Stonewt::show_lbs() const
{
	cout << stone << " stone, " << pds_left << " pounds" << endl;
}

void Stonewt::show_std() const
{
	cout << pounds << " pounds" << endl;
}

main.cpp

#include "stonewt.h"
const int SIZE = 6;

int main(void)
{
	double input;
	Stonewt stonewt_arr[SIZE] = { 275,Stonewt(285.7),Stonewt(21,8) };//初始化前3个
	Stonewt max_pounds = stonewt_arr[0];//最大的值
	Stonewt min_pounds = stonewt_arr[0];//最小的值
	Stonewt eleven = Stonewt(11, 0.0);  //11英石
	unsigned int count = 0;
	
	for (int i = 3; i < SIZE; i++)
	{
		cout << "Enter number" << i + 1 << " element of stonewt_arr(in pounds)" << endl;
		cin >> input;
		stonewt_arr[i] = Stonewt(input);
	}

	for (int i = 0; i < SIZE; i++)
	{
		max_pounds = (max_pounds > stonewt_arr[i]) ? max_pounds : stonewt_arr[i];
		min_pounds = (min_pounds < stonewt_arr[i]) ? min_pounds : stonewt_arr[i];
		if (stonewt_arr[i] > eleven)
		{
			count++;
		}
	}
	cout << "The max weight is: ";
	max_pounds.show_std();
	cout << "The min weight is: ";
	min_pounds.show_std();
	cout << count << " objects are heavier than eleven." << endl;

	return 0;
}

7.复数由两个部分组成:实数部分和虚数部分。复数的一种书写方式是:(3.0, 4.0),其中3.0是实数部分,4.0是虚数部分。假设a=(A,Bi),c = (C, Di),则下面是一些复数运算。

加法:a + c = (A + C, (B+D)i)。
减法:a - c = (A - C, (B-D)i)。
乘法:a * c = (A *C - B*D, (A*d + B*C)i)。
乘法:x*c = (x*C, x * Di),其中x为实数。
共轭:~a = (A, -Bi)

请定义一个复数类,以便下面的程序可以使用它来获得正确的结果。

#include <iostream>
using namespace std;
#include "complex0.h"    // to avoid confusion with complex.h
int main()
{
    complex a(3.0, 4.0); // initialize to (3,4i)
    complex c;
    cout << "Enter a complex number (q to quit):\n";
    while (cin >> c)
    {
        cout << "c is " << c << '\n';
        cout << "complex conjugate is " << ~c << '\n';
        cout << "a is " << a << '\n";
        cout << "a + c is " << a + c << '\n';
        cout << "a - c is " << a - c << '\n';
        cout << "a * c is " << a * c << '\n';
        cout << "2 * c is " << 2 * c << '\n';
        cout << "Enter a complex number (q to quit):\n";
    }
    cout << "Done!\n";
    return 0;
}

注意,必须重载运算符<<和>>。标准C++使用头文件complex提供了比这个示例更广泛的复数支持,因此应将自定义的头文件名为complex0.h,以免发生冲突。应尽可能使用const。
下面是该程序的运行情况。

Enter a complex number (q to quit):
real: 10
imaginary: 12
c is (10,12i)
complex conjugate is (10,-12i)
a is (3,4i)
a + c is (13,16i)
a - c is (-7,-8i)
a * c is (-18,76i)
2 * c is (20,24i)
Enter a complex number (q to quit):
real: q
Done!

请注意,经过重载后,cin >> c将提示用户输入实数和虚数部分。

实现:
complex0.h

#pragma once
#include <iostream>
using namespace std;

class complex0
{
public:
	complex0();
	complex0(double r, double i);
	~complex0();

	complex0 operator+(const complex0& c)const;
	complex0 operator-(const complex0& c)const;
	complex0 operator*(const complex0& c)const;
	friend complex0 operator*(double x, const complex0& c);
	complex0 operator~()const;//共轭
	friend istream& operator>>(istream &is, complex0& c);
	friend ostream& operator<<(ostream& os, const complex0& c);

private:
	double real;//实数
	double imaginary;//虚数
};

complex0.cpp

#include "complex0.h"

complex0::complex0()
{
	real = imaginary = 0.0;
}

complex0::complex0(double r, double i)
{
	real = r;
	imaginary = i;
}

complex0::~complex0()
{
	real = imaginary = 0.0;
}

complex0 complex0::operator+(const complex0& c) const
{
	return complex0(real + c.real, imaginary + c.imaginary);
}

complex0 complex0::operator-(const complex0& c) const
{
	return complex0(real - c.real, imaginary - c.imaginary);
}

complex0 complex0::operator*(const complex0& c) const
{
	return complex0(real * c.real - imaginary*c.imaginary, real * c.imaginary + imaginary * c.real);
}

complex0 complex0::operator~() const
{
	return complex0(real, -imaginary);
}

complex0 operator*(double x, const complex0& c)
{
	return complex0(x * c.real, x * c.imaginary);
}

istream& operator>>(istream& is, complex0& c)
{
	cin >> c.real >> c.imaginary;
	return is;
}

ostream& operator<<(ostream& os, const complex0& c)
{
	cout << "real = " << c.real << ", imaginary = " << c.imaginary << endl;
	return os;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值