C ++ Primer Plus 第六版 第十一章编程练习答案

来源:互联网 发布:明代斗彩天字罐淘宝 编辑:程序博客网 时间:2024/05/17 03:40
1.修改程序清单11.5,使之将一系列连续的随机漫步者位置写入到文件中。对于每个位置,用步号进行标志。另外,让该程序将初始条件(目标距离和步长)以及结果小结写入到该文件中。该文件的内容与下面类似:


Target Distance: 100, Step Size: 20


0: (x,y) = (0, 0)


1: (x,y) = (-11.4715, 16.383)


2: (x,y) = (-868807, -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

//vect.h#include <iostream>#ifndef VECT_H_INCLUDED#define VECT_H_INCLUDEDnamespace 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 // VECT_H_INCLUDED

//main.h#include <cmath>#include <iostream>#include <fstream>#include <cstdlib>#include <ctime>#include "vect.h"using std::sqrt;using std::sin;using std::cos;using std::atan;using std::atan2;using std::cout;static unsigned long steps = 0;namespace VECTOR{const double Rad_to_deg = 45 / atan ( 1 );void Vector::set_mag(){mag = sqrt ( x * x + y * y );}void Vector::set_ang(){if ( x == 0 && y == 0 )ang = 0;elseang = 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;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;set_x();set_y();}else{cout << "Incorrect 3rd argument to Vector() --";cout << "vector set to 0\n";x = y = mag = ang = 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;set_x();set_y();}else{cout << "Incorrect 3rd argument to Vector() --";cout << "vector set to 0\n";x = y = mag = ang = 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 operator* ( double n, const Vector & a ){return Vector ( 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 << ")";}elseos << "Vector object mode is invalid";return os;}*/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 << ")";}elseos << "Vector object mode is invalid";return os;}}int main(){using namespace std;using VECTOR::Vector;ofstream fout("thewalk.txt",ios::out);if(!fout){cerr<<"The file does not exist "<<endl;exit(EXIT_FAILURE);}srand ( time ( 0 ) );double direction;Vector step;Vector result ( 0, 0 );double target;double dstep;cout << "Enter target distance (q to quit): ";while ( cin >> target ){cout << "Enter step distance: ";if ( ! ( cin >> dstep ) )break;fout<<"Target Distance: "<<target<<", "<<"Step Size: "<<dstep<<endl;while ( result.magval() < target ){fout<<steps<<": "<<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";fout << "After" << steps << " steps, the subject has the following location:\n";fout<<result<<endl;cout<<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);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对修改后的版本进行测试,结果应该与以前相同,因为Vecotr类的公有接口与原来相同。

//mian.cpp#include <cmath>#include <iostream>#include <fstream>#include <cstdlib>#include <ctime>#include "vect.h"using std::sqrt;using std::sin;using std::cos;using std::atan;using std::atan2;using std::cout;static unsigned long steps = 0;namespace VECTOR{const double Rad_to_deg = 45 / atan ( 1 );Vector::Vector(){x = y =  0;mode = RECT;}Vector::Vector ( double n1, double n2, Mode form ){mode = form;if ( form == RECT ){x = n1;y = n2;magval();angval();}else if ( form == POL ){double mag = n1;double ang = n2/Rad_to_deg;x = mag*cos(ang);y = mag*sin(ang);}else{cout << "Incorrect 3rd argument to Vector() --";cout << "vector set to 0\n";x = y =  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 ){double mag = n1;double ang = n2/Rad_to_deg;x = mag*cos(ang);y = mag*sin(ang);}else{cout << "Incorrect 3rd argument to Vector() --";cout << "vector set to 0\n";x = y = 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 operator* ( double n, const Vector & a ){return Vector ( 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 << ")";}elseos << "Vector object mode is invalid";return os;}*/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() << ")";}elseos << "Vector object mode is invalid";return os;}}int main(){using namespace std;using VECTOR::Vector;ofstream fout("thewalk.txt",ios::out);if(!fout){cerr<<"The file does not exist "<<endl;exit(EXIT_FAILURE);}srand ( time ( 0 ) );double direction;Vector step;Vector result ( 0, 0 );double target;double dstep;cout << "Enter target distance (q to quit): ";while ( cin >> target ){cout << "Enter step distance: ";if ( ! ( cin >> dstep ) )break;fout<<"Target Distance: "<<target<<", "<<"Step Size: "<<dstep<<endl;while ( result.magval() < target ){fout<<steps<<": "<<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";fout << "After" << steps << " steps, the subject has the following location:\n";fout<<result<<endl;cout<<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);cout << "Enter target distance (q to quit): ";}cout<<"Bye!\n";cin.clear();while(cin.get()!='\n')continue;return 0;}
//vect.h#include <iostream>#ifndef VECT_H_INCLUDED#define VECT_H_INCLUDEDnamespace VECTOR{class Vector{public:enum Mode {RECT, POL};private:double x;double y;Mode mode;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 sqrt ( x * x + y * y );}double angval() const{if ( x == 0 && y == 0 )return 0;elsereturn atan2 ( y, x );}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 // VECT_H_INCLUDED


3.修改程序清单11.15,使之报告N次测试中的最高、最低和平均步数(其中N是用户输入的整数),而不是报告每次测试的结果。
//我就拿第一题的代码,只把main函数里的改掉int main(){using namespace std;using VECTOR::Vector;srand ( time ( 0 ) );double direction;Vector step;Vector result ( 0, 0 );double target;double dstep;int N,i=0,j=0,k=0,l=0,average=0;cout << "Please enter the number of tests(N): ";cin>>N;int a[200];cout << "Enter target distance (q to quit): ";while ( cin >> target ){cout << "Enter step distance: ";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\n\n";a[i]=steps;average+=steps;if(i++==N-1) break;steps = 0;result.reset(0,0);cout << "Enter target distance (q to quit): ";}for(;j<N;j++){if(a[k]<a[j]) k=j;else if(a[l]>a[j]) l=j;}average=average/i;cout<<"max : "<<a[k]<<endl<<"min : "<<a[l]<<endl<<"average : "<<average<<endl;cin.clear();while(cin.get()!='\n')continue;return 0;}

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

//time.h#ifndef TIME_H_INCLUDED#define TIME_H_INCLUDEDclass Time{private:int hours;int minutes;public:Time(){hours = minutes = 0;}Time ( int h, int m ) : hours ( h ), minutes ( m ) {}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 );};#endif // TIME_H_INCLUDED

//main.cpp#include <iostream>#include "time.h"int main(){using std::cout;using std::endl;Time aida ( 3, 35 );Time tosca ( 2, 48 );cout << "Aida and Tosca" << endl;cout << aida << " ; " << tosca << endl;cout << "Aida + Tosca : " << aida + tosca << endl;cout << "Aida - Tosca : " << aida - tosca << endl;cout << "Aida * 1.17 : " << aida * 1.17 << endl;cout << "10 * Tosca : " << 10 * tosca << endl;return 0;}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 sum;int total1 = t1.hours * 60 + t1.minutes;int total2 = t2.hours * 60 + t2.minutes;sum.hours = ( total1 - total2 ) / 60;sum.minutes = ( total1 - total2 ) % 60;return sum;}Time operator* ( const Time & t, double n ){Time sum;int total = ( t.hours * 60 + t.minutes ) * n;sum.hours = total / 60;sum.minutes = total % 60;return sum;}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值进行加、减、乘运算。编写一个使用所有类方法和友元的小程序,来测试这个类。

//main.cpp#include <iostream>#include "stonewt.h"//等下用 t(,,)模式返回using std::cout;using std::endl;int main(){Stonewt a = 275;Stonewt b ( 285.7 );Stonewt c ( 21, 8 );a.setFormat ( Stonewt::st );b.setFormat ( Stonewt::st );c.setFormat ( Stonewt::st );cout << "Stone Format" << endl;cout << "a : " << a << "b : " << b << "c : " << c ;b.setFormat ( Stonewt::ilb );cout << "b : " << b;cout << "a+b : " << a + b<<endl;cout << "c-a : " << c - a<<endl;cout << "a*5 : " << a * 5<<endl;return 0;}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;fmat=st;}Stonewt::~Stonewt(){}Stonewt Stonewt::operator+ ( const Stonewt & s ){Stonewt t;t.pds_left = pds_left + s.pds_left;t.stone = stone + s.stone + t.pds_left / Lbs_per_stn;t.pds_left = int ( t.pds_left ) % Lbs_per_stn + t.pds_left - int ( t.pds_left );t.pounds = pounds + s.pounds;return t;}Stonewt Stonewt::operator- ( const Stonewt & s ){Stonewt t;double temp = pounds - s.pounds;t.stone = int ( temp ) / Lbs_per_stn;t.pds_left = int ( temp ) % Lbs_per_stn + temp - int ( temp );t.pounds = temp;return t;}Stonewt Stonewt::operator* ( double n ){Stonewt t;double temp = pounds * n;t.stone = int ( temp ) / Lbs_per_stn;t.pds_left = int ( temp ) % Lbs_per_stn + temp - int ( temp );t.pounds = temp;return t;}void Stonewt::setFormat ( Format form ){fmat = form;}std::ostream & operator<< ( std::ostream & os, const Stonewt & s ){if ( s.fmat == Stonewt::st )os << s.stone << " Stone ," << s.pds_left << " Pounds" << endl;if ( s.fmat == Stonewt::ilb )os << int ( s.pounds ) << " Pounds(int)" << endl;if ( s.fmat == Stonewt::flb )os << s.pounds << " Pounds(float)" << endl;return os;}
//stonwt.h#ifndef STONEWT_H_INCLUDED#define STONEWT_H_INCLUDEDclass Stonewt{public:enum Format {st, ilb, flb};private:enum {Lbs_per_stn = 14};int stone;double pds_left;double pounds;Format fmat;public:Stonewt ( double lbs );Stonewt ( int stn, double lbs);Stonewt();~Stonewt();void setFormat(Format form);Stonewt operator+ ( const Stonewt & s );Stonewt operator- ( const Stonewt & s );Stonewt operator* ( double n );friend std::ostream & operator<< ( std::ostream & os, const Stonewt & s );};#endif // STONEWT_H_INCLUDED

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

不写了,剩下几题太简单了,虽说我这一题,写了4个小时,嘿嘿嘿