C++ primer plus第十一章编程练习答案

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.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

#include 
#include 
#include 
#include 
#include "vect.h"

int main()
{
    using namespace std;
    using VECTOR::Vector;
    srand(time(0));
    double direction;
    Vector step;
    Vector result(0.0, 0.0);
    unsigned long steps = 0;
    double target;
    double dstep;
    ofstream fout;

    fout.open("temp.txt");
    cout << "Enter target distance (q to quit): ";
    while (cin >> target)
    {
        cout << "Enter step length: ";
        if (!(cin >> dstep))
        {
            break;
        }
        fout << "Target Distance: " << target;
        fout << ", Step Size: " << dstep << endl;
        fout << "0: " << result << endl;
        while (result.magval() < target)
        {
            direction = rand() % 360;
            step.reset(dstep, direction, Vector::POL);
            result = result + step;
            steps++;
            fout << steps << ": " << result << endl;
        }
        fout << "After " << steps << " steps, the subject ";
        fout << "has the following location:\n";
        fout << result << endl;
        result.polar_mode();
        fout << " or\n";
        fout << result << endl;
        fout << "Average outward distance per step = ";
        fout << result.magval() / steps << endl;
        fout << endl;

        cout << "After " << steps << " steps, the subject ";
        cout << "has the following location:\n";
        cout << result << endl;
        result.polar_mode();
        cout << " or\n";
        cout << result << endl;
        cout << "Average outward distance per step = ";
        cout << result.magval() / steps << endl;
        steps = 0;
        result.reset(0.0, 0.0);
        cout << "Enter target distance (q to quit): ";
    }
    cin.clear();
    while (cin.get() != '\n')
        continue;
    fout.close();
    cout << "Bye!\n";

    return 0;
}
#ifndef VECT_H_
#define VECT_H_
#include 

namespace VECTOR
{
    class Vector
    {
    public:
        enum Mode {RECT, POL};

    private:
        double x;
        double y;
        double mag;
        double ang;
        Mode mode;
        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();
        void rect_mode();
        Vector operator+(const Vector &b) const;
        Vector operator-(const Vector &b) const;
        Vector operator-() const;
        Vector operator*(double n) const;
        friend Vector operator*(double n, const Vector &a);
        friend std::ostream &operator<<(std::ostream &os, const Vector &v);
    };
}

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

namespace VECTOR
{
    const double Rad_to_deg = 45.0 / atan(1.0);

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

    void Vector::set_x()
    {
        x = mag * cos(ang);
    }

    void Vector::set_y()
    {
        y = mag * sin(ang);
    }

    Vector::Vector()
    {
        x = y = mag = ang = 0.0;
        mode = RECT;
    }

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

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

    Vector::~Vector()
    {
    }

    void Vector::polar_mode()
    {
        mode = POL;
    }

    void Vector::rect_mode()
    {
        mode = RECT;
    }

    Vector Vector::operator+(const Vector &b) const
    {
        return Vector(x + b.x, y + b.y);
    }

    Vector Vector::operator-(const Vector &b) const
    {
        return Vector(x - b.x, y - b.y);
    }

    Vector Vector::operator-() const
    {
        return Vector(-x, -y);
    }

    Vector Vector::operator*(double n) const
    {
        return Vector(n * x, n * y);
    }

    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.mag << ", ";
            os << v.ang * Rad_to_deg << ")";
        }
        else
        {
            os << "Vector object mode is invalid";
        }
        return os;
    }
}

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

#include 
#include 
#include 
#include "vect.h"

int main()
{
    using namespace std;
    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;
            step.reset(dstep, direction, Vector::POL);
            result = result + step;
            steps++;
        }
        cout << "After " << steps << " steps, the subject ";
        cout << "has the following location:\n";
        cout << result << endl;
        result.polar_mode();
        cout << " or\n";
        cout << result << endl;
        cout << "Average outward distance per step = ";
        cout << result.magval() / steps << endl;
        steps = 0;
        result.reset(0.0, 0.0);
        cout << "Enter target distance (q to quit): ";
    }
    cout << "Bye!\n";

    return 0;
}
#ifndef VECT_H_
#define VECT_H_
#include 

namespace VECTOR
{
    class Vector
    {
    public:
        enum Mode{ RECT, POL };

    private:
        double x;
        double y;
        Mode mode;
        double set_mag() const;             //修改了原来设置矢量长度的函数;
        double set_ang() const;             //修改了原来设置矢量角度的函数;
        void set_x(double mag, double ang); //修改了原来设置矢量x坐标的函数;
        void set_y(double mag, double ang); //修改了原来设置矢量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 set_mag(); }
        double angval() const { return set_ang(); }
        void polar_mode();
        void rect_mode();
        Vector operator+(const Vector &b) const;
        Vector operator-(const Vector &b) const;
        Vector operator-() const;
        Vector operator*(double n) const;
        friend Vector operator*(double n, const Vector &a);
        friend std::ostream &operator<<(std::ostream &os, const Vector &v);
    };
}

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

namespace VECTOR
{
    const double Rad_to_deg = 45.0 / atan(1.0);

    double Vector::set_mag() const
    {
        return sqrt(x * x + y * y); //计算向量的长度;
    }

    double Vector::set_ang() const
    {
        if (x == 0.0 && y == 0.0)
        {
            return 0.0; //若是向量的x坐标和y坐标为0则角度也为0;
        }
        else
        {
            return atan2(y, x); //否则计算向量的角度并返回至调用对象;
        }
    }

    void Vector::set_x(double mag, double ang)
    {
        x = mag * cos(ang);
    }

    void Vector::set_y(double mag, double ang)
    {
        y = mag * sin(ang);
    }

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

    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); //使用修改的设置x坐标的函数来更新x坐标值;
            set_y(n1, n2 / Rad_to_deg); //使用修改的设置y坐标的函数来更新y坐标值;
        }
        else
        {
            cout << "Incorrect 3rd argument to Vector() -- ";
            cout << "vector set to 0\n";
            x = y = 0.0;
            mode = RECT;
        }
    }

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

    Vector::~Vector()
    {
    }

    void Vector::polar_mode()
    {
        mode = POL;
    }

    void Vector::rect_mode()
    {
        mode = RECT;
    }

    Vector Vector::operator+(const Vector &b) const
    {
        return Vector(x + b.x, y + b.y);
    }

    Vector Vector::operator-(const Vector &b) const
    {
        return Vector(x - b.x, y - b.y);
    }

    Vector Vector::operator-() const
    {
        return Vector(-x, -y);
    }

    Vector Vector::operator*(double n) const
    {
        return Vector(n * x, n * y);
    }

    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() << ", ";
            os << v.angval() * Rad_to_deg << ")";
        }
        else
        {
            os << "Vector object mode is invalid";
        }
        return os;
    }
}

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

#include 
#include 
#include 
#include 
#include "vect.h"

int main()
{
    using namespace std;
    using VECTOR::Vector;
    srand(time(0));
    double direction;
    Vector step;
    Vector result(0.0, 0.0);
    unsigned long steps = 0;
    double target = 50.0;
    double dstep = 2.0;
    unsigned long i, n, maxv, minv;
    double average = 0.0;

    cout << "Target distance: " << target << endl;
    cout << "Step length: " << dstep << endl;
    cout << "Please you enter running time: ";
    while (!(cin >> n))
    {
        cin.clear();
        while (cin.get() != '\n')
            continue;
        cout << "Please enter an number: ";
    }
    i = 0, maxv = 0, minv = ULONG_MAX;
    while (i < n)
    {
        while (result.magval() < target)
        {
            direction = rand() % 360;
            step.reset(dstep, direction, Vector::POL);
            result = result + step;
            steps++;
        }
        maxv = maxv < steps ? steps : maxv;
        minv = minv > steps ? steps : minv;
        average += steps;
        cout << "Time #" << i + 1 << ':' << endl;
        cout << "After " << steps << " steps, the subject ";
        cout << "has the following location:\n";
        cout << result << endl;
        result.polar_mode();
        cout << " or\n";
        cout << result << endl;
        cout << "Average outward distance per step = ";
        cout << result.magval() / steps << endl;
        steps = 0;
        result.reset(0.0, 0.0);
        ++i;
    }
    cout << "The maximum steps are: " << maxv << endl;
    cout << "The minimum steps are: " << minv << endl;
    cout << "The average steps are: " << average / n << endl;
    cout << "Bye!\n";

    return 0;
}
#ifndef VECT_H_
#define VECT_H_
#include 

namespace VECTOR
{
    class Vector
    {
    public:
        enum Mode {RECT, POL};

    private:
        double x;
        double y;
        double mag;
        double ang;
        Mode mode;
        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();
        void rect_mode();
        Vector operator+(const Vector &b) const;
        Vector operator-(const Vector &b) const;
        Vector operator-() const;
        Vector operator*(double n) const;
        friend Vector operator*(double n, const Vector &a);
        friend std::ostream &operator<<(std::ostream &os, const Vector &v);
    };
}

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

namespace VECTOR
{
    const double Rad_to_deg = 45.0 / atan(1.0);

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

    void Vector::set_x()
    {
        x = mag * cos(ang);
    }

    void Vector::set_y()
    {
        y = mag * sin(ang);
    }

    Vector::Vector()
    {
        x = y = mag = ang = 0.0;
        mode = RECT;
    }

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

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

    Vector::~Vector()
    {
    }

    void Vector::polar_mode()
    {
        mode = POL;
    }

    void Vector::rect_mode()
    {
        mode = RECT;
    }

    Vector Vector::operator+(const Vector &b) const
    {
        return Vector(x + b.x, y + b.y);
    }

    Vector Vector::operator-(const Vector &b) const
    {
        return Vector(x - b.x, y - b.y);
    }

    Vector Vector::operator-() const
    {
        return Vector(-x, -y);
    }

    Vector Vector::operator*(double n) const
    {
        return Vector(n * x, n * y);
    }

    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.mag << ", ";
            os << v.ang * Rad_to_deg << ")";
        }
        else
        {
            os << "Vector object mode is invalid";
        }
        return os;
    }
}

4.重新编写最后的 Time 类示例(程序清单 11.10程序清单111 和程序清单11.12使用友元数
来实现所有的重载运算符。

#include 
#include "mytime3.h"

int main()
{
    using std::cout;
    using std::endl;
    Time aida(3, 35);
    Time tosca(2, 48);
    Time temp;

    cout << "Aida and Tosca:\n";
    cout << aida << "; " << tosca << endl;
    temp = aida + tosca;
    cout << "Aida + Tosca: " << temp << endl;
    temp = aida * 1.17;
    cout << "Aida * 1.17: " << temp << endl;
    cout << "10.0 * Tosca: " << 10.0 * tosca << endl;

    return 0;
}
#ifndef MYTIME3_H_
#define MYTIME3_H_
#include 

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 &a, const Time &b);
    friend Time operator-(const Time &a, const Time &b);
    friend Time operator*(const Time &t, double n);
    friend Time operator*(double m, const Time &t) { return t * m; }
    friend std::ostream &operator<<(std::ostream &os, const Time &t);
};

#endif
#include "mytime3.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 &a, const Time &b)
{
    Time sum;
    sum.minutes = a.minutes + b.minutes;
    sum.hours = a.hours + b.hours + sum.minutes / 60;
    sum.minutes %= 60;
    return sum;
}

Time operator-(const Time &a, const Time &b)
{
    Time diff;
    int tot1, tot2;
    tot1 = a.minutes + 60 * a.hours;
    tot2 = b.minutes + 60 * b.hours;
    diff.minutes = (tot2 - tot1) % 60;
    diff.hours = (tot2 - tot1) / 60;
    return diff;
}

Time operator*(const Time &t, double mult)
{
    Time result;
    long totalminutes = t.hours * mult * 60 + t.minutes * mult;
    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 值进行加、减、乘运算。编写一个使用所有类方法和友元的小程序,来测试这个类。

#include 
#include "stonewt.h"

int main()
{
    using std::cout;
    using std::endl;
    Stonewt incognito(275, Stonewt::DOUBLE_POUND);
    Stonewt wolfe(285.7, Stonewt::STONE);
    Stonewt taft(21, 8, Stonewt::INT_POUND);

    cout << "Here are the tsets:" << endl;
    cout << "The celebrity weighed ";
    cout << incognito;
    cout << "The detective weighed ";
    cout << wolfe;
    cout << "The President weighed ";
    cout << taft;
    cout << "incognito + wolfe = " << incognito + wolfe;
    cout << "wolfe - incognito = " << wolfe - incognito;
    cout << "taft * 10.0 = " << taft * 10.0;
    cout << "10.0 * taft = " << 10.0 * taft;

    return 0;
}
#ifndef STONEWT_H_
#define STONEWT_H_

class Stonewt
{
public:
    enum Mode { STONE, INT_POUND, DOUBLE_POUND };

private:
    enum { Lbs_per_stn = 14 }; //1英石等于14英镑;
    int stone;
    double pds_left;
    double pounds;
    int pounds_int;
    Mode mode;
    void set_stone();      //设置stone英石变量;
    void set_pounds();     //设置pounds英镑变量;
    void set_pounds_int(); //设置pounds整型英镑变量;

public:
    Stonewt(double lbs, Mode form);
    Stonewt(int stn, double lbs, Mode form);
    Stonewt();
    ~Stonewt();
    void set_stone_mode();                                 //设置英石格式;
    void set_pounds_mode();                                //设置整数磅格式;
    void set_int_pounds_mode();                            //设置浮点磅格式;
    Stonewt operator+(const Stonewt &st) const;            //重载'+'运算符;
    Stonewt operator-(const Stonewt &st) const;            //重载'-'运算符;
    Stonewt operator*(double n) const;                     //重载'*'运算符;
    friend Stonewt operator*(double n, const Stonewt &st); //友元函数重载'*'运算符可以令对象在'*'右边进行操作;
    friend std::ostream &operator<<(std::ostream &os, const Stonewt &st);
};

#endif
#include 
#include "stonewt.h"
using std::cout;
using std::endl;

void Stonewt::set_stone()
{
    stone = int(pounds) / Lbs_per_stn;                           //设置stone英石变量;
    pds_left = int(pounds) % Lbs_per_stn + pounds - int(pounds); //设置pounds磅数剩余变量;
}

void Stonewt::set_pounds()
{
    pounds = stone * Lbs_per_stn + pds_left; //设置pounds英镑变量;
}

void Stonewt::set_pounds_int()
{
    pounds_int = int(pounds + 0.5); //设置pounds英镑整型四舍五入变量;
}

Stonewt::Stonewt(double lbs, Mode form)
{
    mode = form;
    if (mode == STONE)
    {
        stone = int(lbs) / Lbs_per_stn;
        pds_left = int(lbs) % Lbs_per_stn + lbs - int(lbs);
        set_pounds();     //调用函数设置Stonewt类剩余数据;
        set_pounds_int(); //同上;
    }
    else if (mode == INT_POUND)
    {
        pounds_int = int(lbs);
        pounds = lbs;
        set_stone();
    }
    else if (mode == DOUBLE_POUND)
    {
        pounds = lbs;
        set_pounds_int();
        set_stone();
    }
    else
    {
        cout << "Incorrect mode!" << endl;
        cout << "Stonewt set to 0" << endl;
        stone = pounds = pds_left = 0.0;
        mode = STONE;
    }
}

Stonewt::Stonewt(int stn, double lbs, Mode form)
{
    mode = form;
    if (mode == STONE)
    {
        stone = stn;
        pds_left = lbs;
        set_pounds();
        set_pounds_int();
    }
    else if (mode == INT_POUND)
    {
        pounds_int = int(stn * Lbs_per_stn + lbs);
        pounds = stn * Lbs_per_stn + lbs;
        set_stone();
    }
    else if (mode == DOUBLE_POUND)
    {
        pounds = stn * Lbs_per_stn + lbs;
        set_pounds_int();
        set_stone();
    }
    else
    {
        cout << "Incorrect mode!" << endl;
        cout << "Stonewt set to 0" << endl;
        stone = pounds = pds_left = 0.0;
        mode = STONE;
    }
}

Stonewt::Stonewt()
{
    stone = pounds = pds_left = 0.0;
    mode = STONE;
}

Stonewt::~Stonewt()
{
}

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

void Stonewt::set_pounds_mode()
{
    mode = DOUBLE_POUND;
}

void Stonewt::set_int_pounds_mode()
{
    mode = INT_POUND;
}

Stonewt Stonewt::operator+(const Stonewt &st) const
{
    return Stonewt(pounds + st.pounds, st.mode); //调用构造函数进行加法操作并重新设置mode模式;
}

Stonewt Stonewt::operator-(const Stonewt &st) const
{
    return Stonewt(pounds - st.pounds, st.mode); //调用构造函数进行减法操作并重新设置mode模式;
}

Stonewt Stonewt::operator*(double n) const
{
    return Stonewt(pounds * n, mode); //调用构造函数进行乘法操作并重新设置mode模式;
}

Stonewt operator*(double n, const Stonewt &st)
{
    return Stonewt(n * st.pounds, st.mode); //调用非友元函数进行乘法操作;
}

std::ostream &operator<<(std::ostream &os, const Stonewt &st)
{
    if (st.mode == Stonewt::STONE)
    {
        os << st.stone << " stone, " << st.pds_left << " pounds" << endl;
    }
    else if (st.mode == Stonewt::INT_POUND)
    {
        os << st.pounds_int << " pounds(int)" << endl;
    }
    else if (st.mode == Stonewt::DOUBLE_POUND)
    {
        os << st.pounds << " pounds(double)" << endl;
    }
    else
    {
        os << "Incorrect mode!" << endl;
    }
    return os;
}

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

#include 
#include "stonewt.h"

int main()
{
    using std::cin;
    using std::cout;
    using std::endl;
    double val;
    Stonewt minv, maxv;
    Stonewt temp(11, 0.0);
    Stonewt wt[6] = {Stonewt(285.7), Stonewt(21, 8), Stonewt(12.0)};

    int count = 0;
    for (int i = 3; i < 6; i++)
    {
        cout << "Please enter an number for pounds: ";
        while (!(cin >> val))
        {
            cin.clear();
            while (cin.get() != '\n')
                continue;
            cout << "Illegal input! Enter an number: ";
        }
        wt[i] = Stonewt(i + 1, val);
    }
    minv = maxv = wt[0];
    for (int i = 0; i < 6; i++)
    {
        minv = wt[i] < minv ? wt[i] : minv;
        maxv = wt[i] > maxv ? wt[i] : maxv;
        count += wt[i] >= temp;
    }
    cout << "The minimum pounds are: " << minv;
    cout << "The maximum pounds are: " << maxv;
    cout << "There are " << count << " elements more than 11 stones." << endl;

    return 0;
}
#ifndef STONEWT_H_
#define STONEWT_H_
#include 

class Stonewt
{
private:
    enum{ Lbs_per_stn = 14 };
    int stone;
    double pds_left;
    double pounds;

public:
    explicit Stonewt(double lbs);
    Stonewt(int stn, double lbs);
    Stonewt();
    ~Stonewt();
    bool operator<(const Stonewt &st) const;
    bool operator>(const Stonewt &st) const;
    bool operator<=(const Stonewt &st) const;
    bool operator>=(const Stonewt &st) const;
    bool operator==(const Stonewt &st) const;
    bool operator!=(const Stonewt &st) const;
    friend std::ostream &operator<<(std::ostream &os, const Stonewt &st);
};

#endif
#include 
using std::cout;
#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 &st) const
{
    return pounds < st.pounds;
}

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

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

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

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

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

std::ostream &operator<<(std::ostream &os, const Stonewt &st)
{
    os << st.pounds << " pounds.\n";
    return os;
}

7.复数有两个部分组成:实数部分和数部分。复数的一种书写方式是:(3.04.0)其中3.0 是实数部分,4.0是虚数部分。假设 a=(A Bi),c=(CDi),则下面是一些复数运算。
加法: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*Cx*Di),其中x为实数
共:-a=(A,-Bi)。
请定义一个复数类,以便下面的程序可以使用它来获得正确的结果

#include ciostream>
using namespace std;
#include "complex0h" // toavoid confusion withcomplex.hi

nt main()
complexal3.0,4.0): //initialize to(3,4i

complexC;cout cc"Enter acomplex number (g 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 << "Done!\n";

return 0;

注意,必须重载运算符<<和>>标准C++使用头文件 complex 提供了比这个示例更广泛的复数支持因此应将自定义的头文件命名为 complex0.h,以免发生冲突。应尽可能使用 const下面是该程序的运行情况。
Enter a complex number (g to quit]:
real:10
imaginary:12cis:(10,12i)
complex'conjuqate is (10,-12i)
a is (3,4F)
a+cis f13,16i)
a-cisF7,-81)
a*cis(-18,761)
2cis(20,24i)
Enter_acomplex number (a to qit]:
real:g
Done!
请注意,经过重载后,cin >>c将提示用户输入实数和虚数部分

#include 
using namespace std;
#include "complex0.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;
}
#ifndef COMPLEX0_H_
#define COMPLEX0_H_
#include 

class complex
{
private:
    double real;
    double imag;

public:
    complex(double r = 0, double i = 0);
    ~complex();
    complex operator+(const complex &t) const;
    complex operator-(const complex &t) const;
    complex operator*(const complex &t) const;
    complex operator*(double x) const;
    complex operator~() const;
    friend complex operator*(double x, const complex &t) { return t * x; }
    friend std::istream &operator>>(std::istream &is, complex &t);
    friend std::ostream &operator<<(std::ostream &os, const complex &t);
};

#endif
#include 
#include "complex0.h"

complex::complex(double r, double i)
{
    real = r, imag = i;
}

complex::~complex()
{
}

complex complex::operator+(const complex &t) const
{
    return complex(real + t.real, imag + t.imag);
}

complex complex::operator-(const complex &t) const
{
    return complex(real - t.real, imag - t.imag);
}

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

complex complex::operator*(double x) const
{
    return complex(x * real, x * imag);
}

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

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

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

你可能感兴趣的:(c++,primer,plus阅读心得,c++,c++,学习,源码,分享)