ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

C++ Primier Plus(第六版) 第十一章 使用类 编程练习答案

2021-12-27 13:36:53  阅读:156  来源: 互联网

标签:const pounds int double C++ Primier 第六版 Stonewt operator


1. 修改程序清单11.5,使之将一系列连续的随机漫步者位置写入到文件中。对于每个位置,用步号进行标示。另外,让该程序将初始条件(目标距离和步长)以及结果小结写入到该文件中。该文件的内容与下面类似:
Target Distance: 100, Step Size: 20
0: (x,y) = (0,0)
1: (x,y) = (-11.4715, 16.383)
2: (x,y) = (-8.68807, -3.42232)
...
26: (x,y) = (42.2919, -78.2594)
27: (x,y) = (58.6794, -89.7309)
After 27 steps, the subject has the following location:
(x,y) = (58.6749, -89.7309)
or
(m,a) = (107.212, -56.8194)
本题比较容易,重新帮助熟练程序写入文件。vector.h和vector.cpp本章里都有,主函数的程序如下:

// ex1.cpp -- walk random problem
// compile with vector.cpp
#include <fstream>
#include <cstdlib>  // rand(), srand() protypes
#include <ctime> 	// time() protype
#include "vector.h"

int main()
{
	using namespace std;
	using VECTOR::Vector;
//	write in file
	ofstream fout;
	fout.open("walk_random.txt");

	srand(time(0));			//generate a seed of random
	double target;
	double dstep;
	unsigned long steps = 0;
	Vector step;
	Vector result(0.0,0.0);
	cout << "Enter the Target Distance(enter q to quit): ";
	while(cin >> target)
	{
		cout << "Enter the distance of every step: ";
		while(!(cin >> dstep))
		{
			cin.clear();
			while(cin.get() != '\n')
				continue;
			cout << "Bad input, please enter a double value: ";
		}

		fout << "Target Distance: " << target << ", Step Size: " << dstep << endl;
		while(result.mag_val() < target)
		{
			step.reset(dstep, rand() % 360, Vector::POL);
			step.rect_mode();
			fout << steps << ": " << step << endl;
			result = result + step;
			steps++;
		}
		fout << "After " << steps << " steps, the subject has the following location:\n";
		fout << result << endl;
		fout << "or\n";
		result.polar_mode();
		fout << result << endl;
		fout << "Average outward distance per step = " << result.mag_val() / steps << endl;
		cout << "Enter next Target Distance(enter q to quit): ";
	}
	fout.close();
	cout << "Bye\n";
	return 0;
}

运行结果如下:
image
生成的文件如下:
image

2. 对Vector类的头文件(程序清单11.13)和实现文件(程序清单11.14进行修改),使其不再存储矢量的长度和角度,而是在magval()和angvel()被调用时计算它们。
应保留公有接口不变(公有方法及其参数不变),但对私有部分,包括一些私有方法和实现进行修改。然后使用程序清单11.15对修改后的版本进行测试,结果应该与以前相同,因为Vector类的公有接口与原来的相同。
本题首先修改vector.h,将私有成员mag和ang删除,四个set函数删除,接着修改构造函数和reset()函数,修改完之后修改magval()和angvel()函数,最后修改一下友元输出函数,代码如下:

// vector1.h -- Vector class with <<, mode state
// store Vector use x and y
#ifndef VECTOR1_H_
#define VECTOR1_H_
#include <iostream>
namespace VECTOR
{
    class Vector
    {
    public:
        enum Mode{RECT, POL};
    // RECT for rectangular, POL for Polar modes
    private:
        double x;
        double y;
        Mode mode;
    // private methods for setting values;
    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
    // oprator 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);
    };
}   // end namespace VECTOR

#endif
// vector1.cpp -- methods for the Vector class
#include <cmath>
#include "vector1.h"
using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;
using std::cout;

namespace VECTOR
{
    const double Rad_to_deg = 45.0/atan(1.0);
    // should be about 57.2957795130823

    Vector::Vector()
    {
        x = y = 0;
        mode = RECT;
    }

    Vector::Vector(double n1, double n2, Mode form )
    {
        mode = form;
        if(mode == RECT)
        {
            x = n1;
            y = n2;
        }
        else if(mode == POL)
        {
            double ang = n2 / Rad_to_deg;
            x = n1 * cos(ang);
            y = n1 * sin(ang);
        }
        else
        {
            cout << "Incorrect 3rd argument to Vector() --";
            cout << "vector set to 0\n";
            x = y = 0;
            mode = RECT;
        }
    }

    // reset vector from rectangular cooridinates if form is
    // RECT (the default) or else from polar coordinates if
    // form is POL
    void Vector::reset(double n1, double n2, Mode form)
    {
        mode = form;
        if(mode == RECT)
        {
            x = n1;
            y = n2;
        }
        else if(mode == POL)
        {
            double ang = n2 / Rad_to_deg;
            x = n1 * cos(ang);
            y = n1 * sin(ang);
        }
        else
        {
            cout << "Incorrect 3rd argument to Vector() --";
            cout << "vector set to 0\n";
            x = y = 0;
            mode = RECT;
        }
    }

    Vector::~Vector()               // destructor
    {
    }

    double Vector::magval() const
    {
        return sqrt(x * x + y * y);
    }

    double Vector::angval() const
    {
        if(x == 0.0 && y == 0.0)
            return 0;
        else
            return atan2(y,x);
    }

    void Vector::polar_mode()       // set to polar mode
    {
        mode = POL;
    }

    void Vector::rect_mode()        // set to 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
    // mutiply n by Vector a
    Vector operator*(double n, const Vector & a)
    {
        return a * n;
    }

    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;
    }

}       // end namespace VECTOR

运行结果如下:
image
3. 修改程序清单11.15,使之报告N次测试中的最高、最低和平均步数(其中N是用户输入的整数),而不是报告每次的结果。
本题首先要定义一个数组,存储每次实验的结果,然后再写三个函数,计算数组的平均值、最小值和最大值,利用一个循环执行输入times次数的实验,注意需要初始化result,代码如下:

// ex3.cpp -- rand walk problem
// compile with the vect.cpp file
#include <cstdlib>  // rand(), srand() protypes
#include <ctime>    // time() protype
#include "vector1.h"
unsigned long average(unsigned long arr[],int n);
unsigned long findmax(unsigned long arr[],int n);
unsigned long findmin(unsigned long arr[],int n);
int main()
{
    using namespace std;
    using VECTOR::Vector;
    srand(time(0));     // seed random-number generator
    double direction;
    Vector step;
    Vector result(0.0, 0.0);
    double target;
    double dstep;
    int times;
    cout << "Enter target distance: ";
    cin >> target;
    cout << "Enter step length: ";
    cin >> dstep;
    cout << "Enter the times you want to test: ";
    cin >> times;
    unsigned long steps[times];
    for(int i = 0; i < times; i++)
    {
        // initialize and reset result to 0
        steps[i] = 0;
        result.reset(0.0, 0.0); // is necessary

        while(result.magval() < target)
        {
            direction = rand() % 360;
            step.reset(dstep, direction, Vector::POL);
            result = result + step;
            steps[i]++;
        }
    }
    unsigned long steps_max = findmax(steps, times);
    unsigned long steps_min = findmin(steps, times);
    unsigned long steps_ave = average(steps, times);

    cout << "After " << times << " times test:\n";
    cout << "Maximum steps is " << steps_max << endl;
    cout << "Minimun steps is " << steps_min << endl;
    cout << "Average steps is " << steps_ave << endl;
    cout << "Bye!\n";
    cin.clear();
    while(cin.get() != '\n')
        continue;
    return 0;
}

unsigned long average(unsigned long arr[],int n)
{
    unsigned long long sum = 0;
    for(int i = 0; i < n; i++)
    {
        sum += arr[i];
    }
    return sum / n;
}

unsigned long findmax(unsigned long arr[],int n)
{
    unsigned long max = 0;
    for(int i = 0; i < n; i++)
        max = max < arr[i] ? arr[i] : max;
    return max;
}

unsigned long findmin(unsigned long arr[],int n)
{
    unsigned long min = arr[0];
    for(int i = 0; i < n; i++)
        min = min < arr[i] ? min : arr[i];
    return min;
}

运行结果如下:
image
可以看到结果接近100/2的平方,因此是正确的。
4. 重新编写最后的Time类示例(程序清单11.10、程序清单11.11和程序清单11.12),使用友元函数来实现所有的重载运算符。
本题不算难,需要注意的是由于函数到了类外,因此函数不能声明为const的函数。需要修改程序11.10和程序11.11,类使用程序无需修改,程序如下:

// mytime.h -- Time class operator * and << overloading
#ifndef MYTIME_H_
#define MYTIME_H_

#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
    friend Time operator+(const Time & t1, const Time & t2);
    friend Time operator-(const Time & t1, const Time & t2);
    friend Time operator*(const Time & t, double n);
    friend Time operator*(double n, const Time & t) {return t * n;}
    friend std::ostream & operator<<(std::ostream & os,const Time & t);
};
#endif
// mytime.cpp -- implementing Time methods
#include <iostream>
#include "mytime.h"

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

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

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

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

Time operator+(const Time & t1, const Time & t2) 
{
    Time sum;
    sum.hours = t1.hours;
    sum.minutes = t2.minutes;
    sum.AddMin(t2.minutes);
    sum.AddHr(t2.hours);
    return sum;
}

Time operator-(const Time & t1, const Time & t2)
{
    Time diff;
    diff.minutes = t1.minutes - t2.minutes;
    diff.hours = t1.hours - t2.hours;
    if(diff.minutes < 0)
    {
        diff.minutes = 60 - diff.minutes;
        diff.hours -= 1;
    }
    return diff;
}

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

std::ostream & operator<<(std::ostream & os,const Time & t)
{
    os << t.hours << " hours, " << t.minutes << " minutes";
    return os;  // is necessary
}
// usetime3_11_12.cpp -- using the third draft of the Time class
// compile usetime3.cpp and mytime0.cpp together
#include "mytime.h"

int main()
{
    using std::cout;
    using std::cin;
    using std::endl;
    Time weeding(4,35);
    Time waxing(2,47);
    Time total,diff,adjusted;
    cout << "weeding time = " << weeding << endl;
    
    cout << "waxing time = " << waxing << endl;

    total = weeding + waxing;
    cout << "total work time = " << total << endl;

    diff = weeding - waxing;
    cout << "weeding time - waxing time = " << diff << endl;

    adjusted = 1.5 * total;
    cout << "adjusted work time = " << adjusted << endl;

    return 0;
}

运行结果如下:
image
5. 重新编写Stonewt类(程序清单11.16和程序清单11.17),使它有一个状态成员,由该成员控制对象应转换为英石格式、整数磅格式还是浮点磅格式。重载<<运算符,使用它来替换show_stn()和show_lbs()方法。重载加法、减法和乘法运算符,以便可以对Stonewt值进行加、减、乘运算。编写一个使用所有类的小程序,来测试这个类。
本题有两种方式修改,一种是存储时,三种格式的数据都存储,利用mode来区分,需要那种格式的数据以对象成员调用即可;另一种方式是只选择一种格式存储,需要其他格式时,利用计算函数计算值返回。笔者采用的是第二种格式,编写过程中,构造函数遇到了问题,默认参数没有使用,导致出现了输出格式不正确的问题,加了mode = form之后解决,样例代码如下:

// stonewt.h -- definetion for the Stonewt class
#ifndef STONEWT_H_
#define STONEWT_H_
#include <iostream>

using std::ostream;
class Stonewt
{
    public:
    enum MODE {STONE, POUNDS, INT_POUNDS};
    private:
        enum{Lbs_per_stn = 14};     // pounds per stone
        double pounds;              // entire weight in pounds
        MODE mode;
    public:
        Stonewt(double lbs, MODE form = POUNDS);
        Stonewt(int stn, double lbs, MODE form = STONE);
        Stonewt(int lbs, MODE form = INT_POUNDS);
        Stonewt();
        ~Stonewt();
        //get value
        int stone_val() const;
        double pds_left_val() const;
        double pounds_val() const;
        int int_pounds_val() const;

        // set mode
        void pounds_mode();
        void int_pounds_mode();
        void stone_mode();


        // operator + - *
        Stonewt operator+(const Stonewt & st) const;
        Stonewt operator-(const Stonewt & st) const;
        Stonewt operator*(double n) const;
    //friend
        // operator*
        friend Stonewt operator*(double n, const Stonewt & st);

        //operator<<
        friend ostream & operator<<(ostream & os, const Stonewt & st);
};
#endif
// stonewt.cpp -- Stonewt methods
#include "stonewt.h"


// construct Stonewt object from double value
Stonewt::Stonewt(double lbs, MODE form)
{
    mode = form;        // is necessary
    pounds = lbs;
}

// construct Stonewt object from stone, double values
Stonewt::Stonewt(int stn, double lbs, MODE form)
{
    mode = form;
    pounds = stn * Lbs_per_stn + lbs;
}

// construct Stonewt object form int pounds vlaue
Stonewt::Stonewt(int lbs, MODE form)
{
    mode = form;
    pounds = double(lbs);
}

// default constructor, wt = 0
Stonewt::Stonewt()
{
    pounds = 0;
}

Stonewt::~Stonewt()         // destructor
{
}
// get value
int Stonewt::stone_val() const
{
    return int(pounds) / Lbs_per_stn; 
}

double Stonewt::pds_left_val() const
{
    return int(pounds) % Lbs_per_stn + pounds -int(pounds);
}

double Stonewt::pounds_val() const
{
    return pounds;
}

int Stonewt::int_pounds_val() const
{
    return int(pounds);
}

// set mode
void Stonewt::pounds_mode()
{
    mode = POUNDS;
}

void Stonewt::int_pounds_mode()
{
    mode = INT_POUNDS;
}

void Stonewt::stone_mode()
{
    mode = STONE;
}

// operator + - *
Stonewt Stonewt::operator+(const Stonewt & st) const
{
    return Stonewt(pounds + st.pounds);
}

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

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

// friend
Stonewt operator*(double n, const Stonewt & st)
{
    return st * n;
}

ostream & operator<<(ostream & os, const Stonewt & st)
{
    Stonewt::MODE mode;
    mode = st.mode;
    switch (mode)
    {
    case Stonewt::POUNDS: 
            os << "Double pounds: " << st.pounds << " pounds";
            break;
    case Stonewt::STONE:
            os << "Stone: " <<st.stone_val() << " stone, " << st.pds_left_val() << " pounds";
            break;
    case Stonewt::INT_POUNDS:
            os << "Int pounds: " << st.int_pounds_val() << " pounds";
            break;
    default:
            os << "Stonewt object mode is invalid";
            break;
    }
}

// ex5_main.cpp -- test the Stonewt class
// compile with stonewt.cpp
#include "stonewt.h"

int main()
{
	using std::cin;
	using std::cout;
	using std::endl;
	double pounds;
	int number;			// the number of egg
	Stonewt egg;
	Stonewt weight;
	egg = Stonewt(15.0);
	cout << "Enter your weight in pounds: ";
	cin >> pounds;
	weight = Stonewt(pounds);
	cout << "Before ate eggs, your weight:\n";
	cout << weight << endl;
	cout << "Enter the number of egg you eat: ";
	cin >> number;
	cout << "After ate " << number << " eggs, your weight:\n";
	weight = weight + number * egg;
	cout << weight << endl;
	weight.stone_mode();
	cout << weight << endl;
	weight.int_pounds_mode();
	cout << weight << endl;
	return 0;
}

运行结果如下:
image
6. 重新编写Stonewt类(程序清单11.16和程序清单11.17),重载全部6个关系运算符。运算符对pounds成员进行比较,并返回一个bool值。编写一个程序,它声明一个包含6个Stonewt对象的数组,并在数组声明中初始化前三个对象,然后,使用循环来读取用于设置剩余三个数组元素的值。接着报告最小的元素,最大的元素,以及大于或等于11英石元素的数量(最简单的方法是创建一个Stonewt对象,并将其初始化为11英石,然后同其他对象进行比较)
本题考查的重载运算符函数的知识,可以采用友元函数或者成员函数进行重载,笔者采用了友元函数重载的方式,代码如下:

// stonewt.h -- definetion for the Stonewt class
#ifndef STONEWT_H_
#define STONEWT_H_
#include <iostream>

using std::ostream;
class Stonewt
{
    public:
    enum MODE {STONE, POUNDS, INT_POUNDS};
    private:
        enum{Lbs_per_stn = 14};     // pounds per stone
        double pounds;              // entire weight in pounds
        MODE mode;
    public:
        Stonewt(double lbs, MODE form = POUNDS);
        Stonewt(int stn, double lbs, MODE form = STONE);
        Stonewt(int lbs, MODE form = INT_POUNDS);
        Stonewt();
        ~Stonewt();
        //get value
        int stone_val() const;
        double pds_left_val() const;
        double pounds_val() const;
        int int_pounds_val() const;

        // set mode
        void pounds_mode();
        void int_pounds_mode();
        void stone_mode();


        // operator + - *
        Stonewt operator+(const Stonewt & st) const;
        Stonewt operator-(const Stonewt & st) const;
        Stonewt operator*(double n) const;

    //friend
        // operator*
        friend Stonewt operator*(double n, const Stonewt & st);

        // oprator == != < > <= >=
        friend bool operator==(const Stonewt & st1, const Stonewt & st2);
        friend bool operator!=(const Stonewt & st1, const Stonewt & st2);
        friend bool operator>(const Stonewt & st1, const Stonewt & st2);
        friend bool operator<(const Stonewt & st1, const Stonewt & st2);
        friend bool operator<=(const Stonewt & st1, const Stonewt & st2);
        friend bool operator>=(const Stonewt & st1, const Stonewt & st2);
        //operator<<
        friend ostream & operator<<(ostream & os, const Stonewt & st);
};
#endif
// stonewt.cpp -- Stonewt methods
#include "stonewt.h"


// construct Stonewt object from double value
Stonewt::Stonewt(double lbs, MODE form)
{
    mode = form;        // is necessary
    pounds = lbs;
}

// construct Stonewt object from stone, double values
Stonewt::Stonewt(int stn, double lbs, MODE form)
{
    mode = form;
    pounds = stn * Lbs_per_stn + lbs;
}

// construct Stonewt object form int pounds vlaue
Stonewt::Stonewt(int lbs, MODE form)
{
    mode = form;
    pounds = double(lbs);
}

// default constructor, wt = 0
Stonewt::Stonewt()
{
    pounds = 0;
}

Stonewt::~Stonewt()         // destructor
{
}
// get value
int Stonewt::stone_val() const
{
    return int(pounds) / Lbs_per_stn; 
}

double Stonewt::pds_left_val() const
{
    return int(pounds) % Lbs_per_stn + pounds -int(pounds);
}

double Stonewt::pounds_val() const
{
    return pounds;
}

int Stonewt::int_pounds_val() const
{
    return int(pounds);
}

// set mode
void Stonewt::pounds_mode()
{
    mode = POUNDS;
}

void Stonewt::int_pounds_mode()
{
    mode = INT_POUNDS;
}

void Stonewt::stone_mode()
{
    mode = STONE;
}

// operator + - *
Stonewt Stonewt::operator+(const Stonewt & st) const
{
    return Stonewt(pounds + st.pounds);
}

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

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

// friend
Stonewt operator*(double n, const Stonewt & st)
{
    return st * n;
}

bool operator==(const Stonewt & st1, const Stonewt & st2)
{
    return st1.pounds == st2.pounds ? true : false;
}
bool operator!=(const Stonewt & st1, const Stonewt & st2)
{
    return st1.pounds != st2.pounds ? true : false;
}
bool operator>(const Stonewt & st1, const Stonewt & st2)
{
    return st1.pounds > st2.pounds ? true : false;
}
bool operator<(const Stonewt & st1, const Stonewt & st2)
{
    return st1.pounds < st2.pounds ? true : false;
}
bool operator>=(const Stonewt & st1, const Stonewt & st2)
{
    return st1.pounds >= st2.pounds ? true : false;
}
bool operator<=(const Stonewt & st1, const Stonewt & st2)
{
    return st1.pounds <= st2.pounds ? true : false;
}

ostream & operator<<(ostream & os, const Stonewt & st)
{
    Stonewt::MODE mode;
    mode = st.mode;
    switch (mode)
    {
    case Stonewt::POUNDS: 
            os << "Double pounds: " << st.pounds << " pounds";
            break;
    case Stonewt::STONE:
            os << "Stone: " <<st.stone_val() << " stone, " << st.pds_left_val() << " pounds";
            break;
    case Stonewt::INT_POUNDS:
            os << "Int pounds: " << st.int_pounds_val() << " pounds";
            break;
    default:
            os << "Stonewt object mode is invalid";
            break;
    }
}
#include "stonewt.h"

int main()
{
	const int Arsize = 6;
	using std::cin;
	using std::cout;
	using std::endl;
	double lbs;
	Stonewt max;
	Stonewt min;
	int count = 0;
	Stonewt starr[Arsize] = {
		100,200,300
	};
	for(int i = 3; i < Arsize; i++)
	{
		cout << "Enter the weight in pounds: ";
		cin >> lbs;
		starr[i] = Stonewt(lbs);
	}
	cout << "Stonewt array list:\n";
	for(int i = 0; i < Arsize; i++)
		cout << starr[i] << endl;
	cout << endl;
	max = starr[0];
	for(int i = 0; i < Arsize; i++)
	{
		max = max > starr[i] ? max : starr[i];
	}
	cout << "The maximum Stonewt object:\n" << max << endl;
	
	min = starr[0];
	for(int i = 0; i < Arsize; i++)
	{
		min = min < starr[i] ? min : starr[i];
	}
	cout << "The minimum Stonewt object:\n" << min << endl;

	Stonewt st11 = Stonewt(11,0.0);
	for(int i = 0; i < Arsize; i++)
	{
		if(starr[i] >= st11)
			count++;
	}

	cout << "The Stonewt array >= 11 stone number: " << count << endl;
	return 0;
}

运行结果如下:
image
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 = (AC-BD,(AD+BC)i)
  • 乘法::x c = (xC,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);
	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将提示用户输入实数和虚数部分。
本题不算难实现上,对于加减乘运算,采用的是成员函数运算符重载,对于输出,之前输出过,因此没什么大问题,对于输入,重载函数定义时忘了输入不能用const引用,因此刚开始提示错误了,后面修改完善了,输入q离开刚开始没做处理,因此会输出imaginar:后面用if语句解决。
代码如下:

// complex0.h -- defination of complex class
#ifndef COMPLEX0_H_
#define COMPLEX0_H_
#include <iostream>
using std::ostream;
using std::istream;
class complex
{
private:
    double real;
    double imaginary;
public:
    complex(double i, double j);
    complex();
    ~complex();
    // overloading operator + - * and ~
    complex operator+(const complex & c) const;
    complex operator-(const complex & c) const;
    complex operator*(const complex & c) const;
    complex operator~() const;

    // friend 
    friend complex operator*(double n, const complex & c);
    friend istream & operator>>(istream & os, complex & c);
    friend ostream & operator<<(ostream & os, const complex & c);
};
#endif
// complex0.cpp -- methods for complex class
#include "complex0.h"

// constructor
complex::complex(double i, double j)
{
    real = i;
    imaginary = j;
}

complex::complex()  // default 
{
    real = imaginary = 0.0;
}

// deconstructor
complex::~complex()
{
}

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

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

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

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

// friend
complex operator*(double n, const complex & c)
{
    return complex(n * c.real, n * c.imaginary);
}

std::istream & operator>>(std::istream & is, complex & c)
{
    std::cout << "real: ";
    if(is >> c.real)
    {
        std::cout << "imaginary: ";
        is >> c.imaginary;
    }
    return is;
}

std::ostream & operator<<(std::ostream & os, const complex & c)
{
    os << "(" << c.real << ", " << c.imaginary << "i)";
    return os;
}

运行结果如下:
image

标签:const,pounds,int,double,C++,Primier,第六版,Stonewt,operator
来源: https://www.cnblogs.com/Fight-go/p/15733950.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有