C++ Primer Plus章节编程练习第十一章

1

题目

  修改程序清单11.5, 使之将一系列连续的随机漫步者位置写入到文件中。对于每个位置,用步号进行标示。另外,让该程序将初始条件(目标距离和步长)以及结果小结写入到该文件中。该文件的内容与下面类似:

Target Dinstance: 100, Step size: 20
0: (x,y) = (0, 0)
1: (x,y) = (-4.15823, 19.563)
2: (x,y) = (8.69752, 4.24206)
3: (x,y) = (23.3246, -9.3979)
4: (x,y) = (43.0207, -12.8709)
5: (x,y) = (29.1276, -27.2577)
6: (x,y) = (42.5102, -42.1206)
7: (x,y) = (29.6544, -57.4414)
8: (x,y) = (20.265, -75.1004)
9: (x,y) = (39.4902, -80.6131)
10: (x,y) = (22.3469, -70.3124)
11: (x,y) = (16.1666, -89.3335)
12: (x,y) = (-2.24354, -97.1481)
13: (x,y) = (6.20882, -115.274)
After 13 steps, the subject has the following location:
(x,y) = (6.20882, -115.274)
 or
(m,a) = (115.441, -86.917)
Average outward distance per step = 8.88011

题解

#include<iostream>
#include<fstream>
#include<cmath>
#include<cstdlib>
#include<ctime>
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);
        //重置vector的值
        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);        
    };
    //具体实现
    //定义常量
    const double Rad_to_deg=45.0/atan(1.0);
    //私有方法
    void Vector::set_mag(){
        mag=std::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{
            std::cout<<"Incorrect 3rd argument to Vector()    ";
            std::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{
            std::cout<<"Incorrect 3rd argument to Vector()    ";
            std::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(x*n,y*n);
    }
    //重载友元的*,直接借用了vector*double的重载,利于维护
    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<<", "<<v.ang*Rad_to_deg<<")";
        }
        else
            os<<"Vector object mode is invalid";
        return os;
    }
}
int main(){
    using namespace std;
    using VECTOR::Vector;
    ofstream output("1.txt");
    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;
        output<<"Target Dinstance: "<<target<<", Step size: "<<dstep<<endl;
        while(result.magval()<target){
            output<<steps<<": "<<result<<endl;//文件中输出步进结果
            direction=rand()%360;           //随机确定方向
            step.reset(dstep,direction,Vector::POL);
            result=result+step;
            steps++;
        }
        //文件输出
        output<<steps<<": "<<result<<endl;//文件中输出步进结果
        output<<"After "<<steps<<" steps, the subject "
                "has the following location:\n";
        output<<result<<endl;
        result.polar_mode();
        output<<" or\n"<<result<<endl;
        output<<"Average outward distance per step = "
              <<result.magval()/steps<<endl;
        //屏幕显示
        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!\n";
    cin.clear();
    while(cin.get()!='\n')
        continue;
    return 0;
}

2

题目

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

题解

#include<iostream>
#include<cmath>
#include<cstdlib>
#include<ctime>
namespace VECTOR{
    class Vector{
    public:
        enum Mode{RECT,POL};
    private:
        double x;
        double y;
/////////////////////////////////////////////////////////////////////////////////////// 删除mag和ang
        Mode mode;
        //私有方法
/////////////////////////////////////////////////////////////////////////////////////// 增加参数
        void set_x(double mag,double ang);
        void set_y(double mag,double ang);
    public:
        Vector();
        Vector(double n1,double n2,Mode form=RECT);
        //重置vector的值
        void reset(double n1,double n2,Mode form=RECT);
        ~Vector();
        //返回私有成员的值
        double xval()const{return x;}
        double yval()const{return y;}
/////////////////////////////////////////////////////////////////////////////////////// 改动
        //计算mag和ang
        double magval()const;
        double angval()const;
/////////////////////////////////////////////////////////////////////////////////////// 
        //切换模式
        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);        
    };
    //具体实现
    //定义常量
    const double Rad_to_deg=45.0/atan(1.0);
/////////////////////////////////////////////////////////////////////////////////////// 改动
    //计算mag和ang
    double Vector::magval()const{
        return std::sqrt(x*x+y*y);
    }
    double Vector::angval()const{
        if(x==0.0&&y==0.0)
            return 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);
            set_y(n1,n2/Rad_to_deg);
        }
        else{
            std::cout<<"Incorrect 3rd argument to Vector()    ";
            std::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{
            std::cout<<"Incorrect 3rd argument to Vector()    ";
            std::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(x*n,y*n);
    }
    //重载友元的*,直接借用了vector*double的重载,利于维护
    Vector operator*(double n,const Vector&a){
        return a*n;
    }
/////////////////////////////////////////////////////////////////////////////////////// 输出函数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;
    }
}
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 "
            "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!\n";
    cin.clear();
    while(cin.get()!='\n')
        continue;
    return 0;
}

3

题目

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

题解

#include<iostream>
#include<cmath>
#include<cstdlib>
#include<ctime>
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);
        //重置vector的值
        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);        
    };
    //具体实现
    //定义常量
    const double Rad_to_deg=45.0/atan(1.0);
    //私有方法
    void Vector::set_mag(){
        mag=std::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{
            std::cout<<"Incorrect 3rd argument to Vector()    ";
            std::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{
            std::cout<<"Incorrect 3rd argument to Vector()    ";
            std::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(x*n,y*n);
    }
    //重载友元的*,直接借用了vector*double的重载,利于维护
    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<<", "<<v.ang*Rad_to_deg<<")";
        }
        else
            os<<"Vector object mode is invalid";
        return os;
    }
}
///////////////////////////////////////////////////////////// 仅修改了main函数
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;       //每一步长
    int sum=0;          //总的步数
    int n;              //测试次数
    int maxstep,minstep;//最多次数和最少次数
    //随机漫步
    cout<<"Enter the times you want to test: ";
    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;           //随机确定方向
            step.reset(dstep,direction,Vector::POL);
            result=result+step;
            steps++;
        }
        sum+=steps;
        if(i==0) minstep=maxstep=steps;
        minstep=steps<minstep?steps:minstep;
        maxstep=steps>maxstep?steps:maxstep;
        steps=0;
        result.reset(0.0,0.0);
    }
    if(n){
        cout<<"The MAX steps = "<<maxstep<<endl
            <<"The MIN steps = "<<minstep<<endl
            <<"The average steps = "<<sum/n<<endl;
    }
    else
        cout<<"No step!\n";
    cout<<"Bye!\n";
    cin.clear();
    while(cin.get()!='\n')
        continue;
    return 0;
}

4

题目

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

题解

#include<iostream>
using namespace std;
class Time{
private:
    int hours;
    int minutes;
public:
    Time();
    Time(int h,int m=0);
    void AddMin(int m);
    void AddHr(int n);
    void Reset(int h=0,int m=0);
    //重载+运算符,替代mytime0中的sum函数
    //全部改为友元函数,因此调用者本身要作为参数显性传入
    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 m,const Time &t){return t*m;};
    friend std::ostream & operator<<(std::ostream &os,const Time  &t);   
};
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 sum;
    //同一个类,所以类的方法可以访问其他类对象的私有成员
    sum.minutes=t1.minutes+t2.minutes;
    sum.hours=t1.hours+t2.hours+sum.minutes/60;
    sum.minutes%=60;
    return sum;
}
Time operator-(const Time &t1,const Time &t2){
    Time diff;
    int tot1,tot2;
    tot1=t1.minutes+60*t1.hours;
    tot2=t2.minutes+60*t2.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;
}
int main(){
    Time aida(3,35);
    Time tosca(2,47);
    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;
}

5

题目

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

题解

#include<iostream>
class Stonewt{
private:
    enum{Lbs_pre_stn=14};
    enum Mode{STN,LBS};
    int stone;
    double pds_left;
    double pounds;
    Mode mode;
public:
    //构造函数和析构函数
    Stonewt(double lbs,Mode m=LBS);
    Stonewt(int stn,double lbs,Mode m=STN);
    Stonewt();
    ~Stonewt();
    //设置模式
    void setSTN(){mode=STN;}
    void setLBS(){mode=LBS;}
    //重载的<<运算符
    friend std::ostream& operator<<(std::ostream &os, const Stonewt &stn);
};
Stonewt::Stonewt(double lbs,Mode m){
    stone=int(lbs)/Lbs_pre_stn;
    pds_left=int(lbs)%Lbs_pre_stn+lbs-int(lbs);
    pounds=lbs;
    mode=m;
}
Stonewt::Stonewt(int stn,double lbs,Mode m){
    stone=stn;
    pds_left=lbs;
    pounds=stn*Lbs_pre_stn+lbs;
    mode=m;
}
Stonewt::Stonewt(){
    stone=pounds=pds_left=0;
}
Stonewt::~Stonewt(){

}
std::ostream& operator<<(std::ostream &os, const Stonewt &stn){
    if(stn.mode==Stonewt::STN)
        os<<stn.stone<<" stone, "<<stn.pds_left<<" pounds\n";
    else if(stn.mode==Stonewt::LBS)
        os<<stn.pounds<<" pounds\n";
    return os;
}
void display(const Stonewt &st, int n);
int main(){
    using std::cout;
    Stonewt incognito=275;              //隐式转换,使用一个参数的构造函数创建一个临时变量,然后赋值给incognito
    Stonewt wolfe(285.7);               //调用一个参数的构造函数
    Stonewt taft(21,8);                 //调用两个参数的构造函数

    cout<<"The celebrity weighed ";
    incognito.setSTN();
    cout<<incognito;
    cout<<"The detective weighed ";
    wolfe.setSTN();
    cout<<wolfe;
    cout<<"The President weighed ";
    taft.setLBS();
    cout<<taft;
    incognito=276.8;                    //赋值会有隐式转换
    taft=325;
    cout<<"After dinner, the celebrity weighed ";
    incognito.setSTN();
    cout<<incognito;
    cout<<"After dinner, the President weighed ";
    cout<<taft;
    display(taft,2);
    cout<<"The wrestler weighed even more.\n";
    display(422,2);                     //调用过程中因为要匹配参数,所以也会进行隐式转换
    cout<<"No stone left unearned\n";
    return 0;
}
void display(const Stonewt &st,int n){
    for(int i=0;i<n;i++){
        std::cout<<"Wow! ";
        std::cout<<st;
    }
}

6

题目

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

题解

#include<iostream>
class Stonewt{
private:
    enum{Lbs_pre_stn=14};
    int stone;
    double pds_left;
    double pounds;
public:
    //构造函数和析构函数
    Stonewt(double lbs);    //只有一个参数的构造函数可以当作隐式转换函数,可以通过使用explicit关键字关闭这种隐式转换特性
    Stonewt(int stn,double lbs);
    Stonewt();
    ~Stonewt();
    void show_lbs()const;   //以pounds格式显示
    void show_stn()const;   //以stone格式显示
    //重载关系运算符
    bool operator==(const Stonewt& stn)const{return pounds==stn.pounds;}
    bool operator!=(const Stonewt& stn)const{return !(*this==stn);}         //直接使用==判定取反
    bool operator<(const Stonewt& stn)const{return pounds<stn.pounds;}
    bool operator>(const Stonewt& stn)const{return pounds>stn.pounds;}
    bool operator<=(const Stonewt& stn)const{return pounds<=stn.pounds;}
    bool operator>=(const Stonewt& stn)const{return pounds>=stn.pounds;}
};
Stonewt::Stonewt(double lbs){
    stone=int(lbs)/Lbs_pre_stn;
    pds_left=int(lbs)%Lbs_pre_stn+lbs-int(lbs);
    pounds=lbs;
}
Stonewt::Stonewt(int stn,double lbs){
    stone=stn;
    pds_left=lbs;
    pounds=stn*Lbs_pre_stn+lbs;
}
Stonewt::Stonewt(){
    stone=pounds=pds_left=0;
}
Stonewt::~Stonewt(){

}
void Stonewt::show_stn()const{
    std::cout<<stone<<" stone, "<<pds_left<<" pounds\n";
}
void Stonewt::show_lbs()const{
    std::cout<<pounds<<" pounds\n";
}
int main(){
    using std::cin;
    using std::cout;
    Stonewt stns[6]={5.3,7.6,12.4};
    for(int i=3;i<6;i++){
        double temp;
        cout<<"Enter the pounds: ";
        cin>>temp;
        stns[i]=temp;
    }
    Stonewt pivort(11);
    Stonewt MAX,MIN;
    int cnt=0;
    for(int i=0;i<6;i++){
        if(i==0)
            MAX=MIN=stns[0];
        else{
            if(stns[i]>MAX) MAX=stns[i];
            if(stns[i]<MIN) MIN=stns[i];  
        }
        if(stns[i]>=pivort) cnt++; 
    }
    cout<<"The MAX one is :\n";
    MAX.show_stn();
    cout<<"The MIN one is :\n";
    MIN.show_stn();
    cout<<"The number of more than 11 pounds: "<<cnt<<'\n';
    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;
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<<"comples 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将提示用户输入实数和虚数部分。

题解

  将定义、实现和main函数写成一个单文件如下所示:

#include<iostream>
using namespace std;
class complex{
private:
    double imaginary_;
    double real_;
public:
    complex(double real=0.0, int imaginary=0.0):real_(real),imaginary_(imaginary){}
    ~complex(){}
    //成员函数重载运算符
    complex operator+(const complex &cpx)const;
    complex operator-(const complex &cpx)const;
    complex operator*(const complex &cpx)const;
    complex operator~()const;
    //友元函数重载运算符
    friend complex operator*(const double n, const complex &cpx);
    friend ostream & operator<<(ostream &os,const complex &cpx);
    friend istream & operator>>(istream &is,complex &cpx);
};
//成员函数重载运算符
complex complex::operator+(const complex &cpx)const{
    return complex(real_+cpx.real_,imaginary_+cpx.imaginary_);
}
complex complex::operator-(const complex &cpx)const{
    return complex(real_-cpx.real_,imaginary_-cpx.imaginary_);
}
complex complex::operator*(const complex &cpx)const{
    return complex(real_*cpx.real_-imaginary_*cpx.imaginary_, real_*cpx.imaginary_+imaginary_*cpx.real_);
}
complex complex::operator~()const{
    return complex(real_,-imaginary_);
}
//友元函数重载运算符
complex operator*(const double n, const complex &cpx){
    return cpx*n;           //复用成员重载*
}
ostream & operator<<(ostream &os,const complex &cpx){
    os<<"("<<cpx.real_<<","<<cpx.imaginary_<<"i)";
    return os;
}
istream & operator>>(istream &is,complex &cpx){
    cout<<"real: ";
    is>>cpx.real_; 
    if(!is) return is;      //如果读入错误直接返回,要符合题目的输出情况
    cout<<"imaginary: ";
    is>>cpx.imaginary_;
    return is;
}
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<<"comples 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;
}

当珍惜每一片时光~