C++ Primer Plus(6th edition)课后习题第11章使用类
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
//randwalk.cpp
#include<iostream>
#include<cstdlib> //rand(),srand()原型
#include<ctime> //time()原型
#include<fstream>
#include"vect.h"
using namespace std;
int main()
{
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("savesteps.txt");
cout << "Enter target distance (q to quit): ";
while (cin >> target)
{
cout << "Enter step length: ";
if (!(cin >> dstep))
break;
fout << "Target Distance: " << target << " Step Size: " << dstep << 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";
cout << result << endl;
fout << "After " << steps << " steps, the subject "
"has the following location:\n";
fout << result << endl;
result.polar_mode();
cout << " or\n" << result << endl;
cout << "Average outward distance per step = "
<< result.magval() / steps << endl;
fout << " or\n" << result << endl;
fout << "Average outward distance per step = "
<< result.magval() / steps << endl;
steps = 0;
result.reset(0.0, 0.0);
cout << "Enter target distance (q to quit): ";
}
cout << "Bye!\n";
cin.clear();
while (cin.get() != '\n')
continue;
cin.get();
return 0;
}
运行结果:
Target Distance: 90 Step Size: 8.9
0: (x,y) = (0, 0)
1: (x,y) = (7.0133, 5.47939)
2: (x,y) = (11.4633, -2.22824)
3: (x,y) = (6.35847, 5.06221)
4: (x,y) = (0.757514, -1.85438)
5: (x,y) = (9.5223, -0.308916)
6: (x,y) = (12.1244, 8.2022)
7: (x,y) = (20.9378, 6.96356)
8: (x,y) = (29.7026, 5.41809)
......
After 153 steps, the subject has the following location:
(x,y) = (91.3235, -37.0908)
or
(m,a) = (98.5683, -22.1044)
Average outward distance per step = 0.644237
*题目核心在于:fout << steps << ": " << result << endl;
通过重载<<运算符使得在RECT模式下以(x,y)形式输出对应坐标到文件中。
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
2.对于Vector类的头文件(程序清单11.13)和实现文件(程序清单11.14)进行修改,使其不再储存矢量的长度和角度,而是在magval()和angval()被调用时计算它们。
应保留公有接口不变(公有方法及其参数不变),但对私有部分(包括一些私有方法)和方法实现进行修改。然后,使用程序清单11.15对修改后的版本进行测试,结果应该与以前相同,因为Vecotr类的公有接口与原来相同。
//vect.h
#ifndef VECTOR_H_
#define VECTOR_H_
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <ctime>
using namespace std;
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);
void set_y(double mag, double ang);
public:
Vector();
Vector(double n1, double n2, Mode form = RECT);
void reset(double n1, double n2, Mode form = RECT);
~Vector();
double xval()const { return x; }
double yval()const { return y; }
double magval()const { 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 ostream & operator<<(ostream &os, const Vector &v);
};
}
#endif
vector.cpp
#include"vect.h"
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;
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
{
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;
}
ostream &operator<<(ostream &os, const Vector &v)
{
if (v.mode == Vector::RECT)
os << "(x,y) = (" << v.x << ", " << v.y << ")";
else if (v.mode == Vector::POL)
{
//更新:Vector类不不存储矢量长度和方向,改为被调用时计算
os << "(m,a) = (" << v.set_mag() << ", "
<< v.set_ang()*Rad_to_deg << ")";
}
else
os << "Vector object mode is invalid";
return os;
}
}
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
3. 修改程序清单11.15,使之报告N次测试中的最高、最低和平均步数(其中N是用户输入的整数),而不是报告每次测试的结果。
#include "vect.h"
int main()
{
using VECTOR::Vector;
srand(time(0));
double direction;
Vector step;
Vector result(0.0, 0.0);
unsigned long steps = 0;
double target;
double dstep;
double numbers, N;
double Min, Max, Sum, Average;
cout << "Enter target distance: ";
cin >> target;
cout << "Enter step length: ";
cin >> dstep;
cout << "Enter test numbers: ";
cin >> numbers;
N = numbers;
Min = Max = Sum = Average = 0.0;
while (numbers) //共进行numbers次测试
{
while (result.magval() < target)
{
direction = rand() % 360;
step.reset(dstep, direction, Vector::POL);
result = result + step;
steps++;
}
cout << "After " << steps << " steps once a walk\n";
if (Min == 0 || Max == 0)
Min = Max = steps;
if (Min > steps)
Min = steps; //如果最低记录被打破,更新
if (Max < steps)
Max = steps; //如果最高纪录被打破,更新
Sum += steps;
numbers--;
steps = 0;
result.reset(0.0, 0.0);
} //while (numbers)
Average = Sum / N;
cout << "Max steps is " << Max << endl;
cout << "Min steps is " << Min << endl;
cout << "Average steps is " << Average << endl;
cout << "Bye!\n";
cin.clear();
while (cin.get() != '\n')
continue;
cin.get();
return 0;
}
*题目核心:
if (Min == 0 || Max == 0)
Min = Max = steps;
if (Min > steps)
Min = steps; //如果最低记录被打破,更新
if (Max < steps)
Max = steps; //如果最高纪录被打破,更新
当进入while(numbers)循环,每轮将与上一轮进行比较。
程序运行结果:
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
4.重新编写最后的Time了示例(程序清单11.10、程序清单11.11和程序清单11.12),使用友元函数来实现所有的重载运算符。
//mytime.h
#ifndef MYTIME_H_
#define MYTIME_H_
#include <iostream>
#include <string>
#include <stdio.h>
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 h);
void Reset(int h = 0, int m = 0);
Time operator*(double n)const;
friend Time operator-(const Time &t1, const Time &t2);
friend Time operator+(const Time &t1, const Time &t2);
friend Time operator*(double m, const Time &t)
{
return t * m;
}
friend ostream & operator<<(ostream & os, const Time &t);
};
#endif
//mytime.cpp
#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;
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 = (tot1 - tot2) % 60;
diff.hours = (tot1 - tot2) / 60;
return diff;
}
Time Time::operator*(double mult)const
{
Time result;
long totalminutes = hours * mult * 60 + minutes * mult;
result.hours = totalminutes / 60;
result.minutes = totalminutes % 60;
return result;
}
ostream &operator<<(ostream &os, const Time &t)
{
os << t.hours << " hours, " << t.minutes << " minutes";
return os;
}
//usetime.cpp
#include "mytime.h"
int main()
{
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 - tosca;
cout << "Aida - Tosca: " << temp << endl;
temp = aida * 1.17;
cout << "Aida * 1.17: " << temp << endl;
cout << "10.0 * Tosca: " << 10.0 * tosca << endl;
cin.get();
return 0;
}
第11章其他练习题请参阅完整代码:
下载链接: