1.修改程序清单11.15,使之将一系列连续的随机漫步者位置写入到文件中。对于每个位置,用步号进行标示。另外,让该程序将初始条件(目标距离和步长)以及结果小结写入到该文件中。
#include <iostream>#include <cstdlib>#include <ctime>#include <fstream>#include "vector.h"using namespace std;using VECTOR::Vector;int main() { ofstream outFile; outFile.open("exercise1.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; outFile << "Target Distance: " << target << ", Step Size: " << dstep << endl; while (result.magval() < target) { direction = rand() % 360; step.set(dstep, direction, 'p'); result = result + step; outFile << steps << ": (x,y) = " << "(" << step.xval() << ", " << step.yval() << ")" << endl; steps++; } outFile << "After " << steps << " steps, the subject " "has the following location:\n"; outFile << "(x,y)=" << result << endl; result.polar_mode(); outFile << " or\n" << result << endl; outFile << "Average outward distance per step = " << result.magval() / steps << endl; outFile << "===================================================="<<endl; outFile << "COPYRIGHT 2018 WWW.YUSHUAI.XYZ" << endl; steps = 0; result.set(0.0, 0.0); cout << "Enter target distance (q to quit): "; } outFile.close(); cout << "Bye~" << endl; system("pause"); return 0;}
2.对Vector类的头文件(程序清单11.13)和实现文件(程序清单11.14)进行修改,使其不再存储矢量的长度和角度,而是在magval()和angval()被调用时计算它们。
应保留公有接口不变(公有方法及其参数不变),但对私有部分(包括一些私有方法)和方法实现进行修改。然后,使用程序清单11.15对修改后的版本进行测试,结果应该与以前相同,因为Vector类的公有接口与原来相同。
vector.h
// vect.h -- Vector class with <<, mode state#ifndef VECTOR_H_#define VECTOR_H_#include <iostream>namespace VECTOR{ class Vector { private: double x; // horizontal value double y; // vertical value char mode; // 'r' = rectangular, 'p' = polar // private methods for setting values void set_x(double mag, double ang); void set_y(double mag, double ang); public: Vector(); Vector(double n1, double n2, char form = 'r'); void set(double n1, double n2, char form = 'r'); ~Vector(); double xval() const { return x; } // report x value double yval() const { return y; } // report y value double magval() const { return sqrt(x * x + y * y); } // report magnitude double angval() const// report angle { if (x == 0.0 && y == 0.0) return 0.0; else return atan2(y, x); } void polar_mode(); // set mode to 'p' void rect_mode(); // set mode to 'r' // operator 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#pragma once
vector.cpp
#include <cmath>#include "vector.h" // includes <iostream>using std::sqrt;using std::sin;using std::cos;using std::atan2;using std::cout;namespace VECTOR{ const double Rad_to_deg = 57.2957795130823; // private methods // calculates magnitude from x and y // set x from polar coordinate void Vector::set_x(double mag, double ang) { x = mag * cos(ang); } // set y from polar coordinate void Vector::set_y(double mag, double ang) { y = mag * sin(ang); } // public methods Vector::Vector() // default constructor { x = y = 0.0; mode = 'r'; } // construct vector from rectangular coordinates if form is r // (the default) or else from polar coordinates if form is p Vector::Vector(double n1, double n2, char form) { mode = form; if (form == 'r') { x = n1; y = n2; } else if (form == 'p') { set_x(n1, n2); set_y(n1, n2); } else { cout << "Incorrect 3rd argument to Vector() -- "; cout << "vector set to 0\n"; x = y = 0.0; mode = 'r'; } } // set vector from rectangular coordinates if form is r (the // default) or else from polar coordinates if form is p void Vector::set(double n1, double n2, char form) { mode = form; if (form == 'r') { x = n1; y = n2; } else if (form == 'p') { set_x(n1, n2); set_y(n1, n2); } else { cout << "Incorrect 3rd argument to Vector() -- "; cout << "vector set to 0\n"; x = y = 0.0; mode = 'r'; } } Vector::~Vector() // destructor { } void Vector::polar_mode() // set to polar mode { mode = 'p'; } void Vector::rect_mode() // set to rectangular mode { mode = 'r'; } // 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); } // multiple vector by n Vector Vector::operator*(double n) const { return Vector(n * x, n * y); } // friend methods // multiply n by Vector a Vector operator*(double n, const Vector & a) { return a * n; } // display rectangular coordinates if mode is r, // else display polar coordinates if mode is p std::ostream & operator<<(std::ostream & os, const Vector & v) { if (v.mode == 'r') os << "(x,y) = (" << v.x << ", " << v.y << ")"; else if (v.mode == 'p') { os << "(m,a) = (" << v.magval() << ", " << v.angval() * Rad_to_deg << ")"; } else os << "Vector object mode is invalid"; return os; }} // end namespace VECTOR
3.修改程序清单11.15,使之报告N次测试中的最高、最低和平均步数(其中N是用户输入的整数),而不是报告每次测试的结果。
#include<iostream>#include<cstdlib>#include<ctime>#include "vector.h"using namespace std;using VECTOR::Vector;int main() { srand(time(0)); double direction; Vector step; Vector result(0.0, 0.0); unsigned long steps = 0; double target; double dstep; unsigned long max = 0; unsigned long min = 999; double avg = 0; int N; cout << "请输入测试的次数:N="; cin >> N; cout << "第一次:" << endl; int i; for (i = 0; i < N; i++) { cout << "Enter target distance(ONLY ENTER NUMBER): "; cin >> target; cout << "Enter step length: "; if (!(cin >> dstep)) break; while (result.magval() < target) { direction = rand() % 360; step.set(dstep, direction, 'p'); result = result + step; steps++; } if (max < steps) max = steps; if (min > steps) min = steps; avg += steps; result.polar_mode(); steps = 0; result.set(0.0, 0.0); } avg /= N; cout << "max: " << max << endl << "min: " << min << endl << "average: " << avg << endl; cout << "Bye~"; system("pause"); return 0;}
4.重新编写最后的Time类示例(程序清单11.10、程序清单11.11和程序清单11.12),使用友元函数来实现所有的重载运算符。
mytime3.h
#pragma once#ifndef MYTIME3_H_#define MYTIME3_H_#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 h); void Reset(int h = 0, int m = 0); 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 ostream & operator<<(ostream & os, const Time & t);};#endif // !MYTIME_H_
mytime3.cpp
#include<iostream>#include "mytime3.h"using namespace std;Time::Time() { hours = minutes = 0;}Time::Time(int h, int m) { hours = h; minutes = m;}void Time::AddMin(int m) { minutes += m; hours += minutes / 0; 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 = t2.minutes + 60 * t2.hours; tot2 = t1.minutes + 60 * t1.hours; diff.minutes = (tot2 - tot1) % 60; diff.hours = (tot2 - tot1) / 60; return diff;}Time operator*(const Time &t, double n) { Time result; long totalminutes = t.hours*n * 60 + t.minutes*n; 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;}
usetime3.cpp
#include<iostream>#include"mytime3.h"using namespace std;int main() { Time aida(3, 35); Time tosca(2, 48); Time temp; cout << "Aida and Tosca:\n"; cout << aida << ";" << tosca << endl; temp = aida + tosca; temp = aida*1.17; cout << "Aida*1.17: " << temp << endl; cout << "10*Tosca: " << 10 * tosca << endl; system("pause"); return 0;}
5.重新编写Stonewt类(程序清单11.16和程序清单11.17),使它有一个状态成员,由该成员控制对象应转换为英石格式、整数磅格式还是浮点磅格式。重载<<运算符,使用它来替换show_stn()和show_lbs()方法。重载加法、减法和乘法运算符,以便可以对Stonewt值进行加、减、乘运算。编写一个使用所有类方法和友元的小程序,来测试这个类。
stonewt.h
// stonewt.h -- definition for the Stonewt class#ifndef STONEWT_H_#define STONEWT_H_class Stonewt{private: enum {Lbs_per_stn = 14}; // pounds per stone int stone; // whole stones double pds_left; // fractional pounds double pounds; // entire weight in poundspublic: Stonewt(double lbs); // constructor for double pounds Stonewt(int stn, double lbs); // constructor for stone, lbs Stonewt(); // default constructor ~Stonewt(); void show_lbs() const; // show weight in pounds format void show_stn() const; // show weight in stone format};#endif
stonewt.cpp
// stonewt.cpp -- Stonewt methods#include <iostream>using std::cout;#include "stonewt.h"// construct Stonewt object from double valueStonewt::Stonewt(double lbs){ stone = int (lbs) / Lbs_per_stn; // integer division pds_left = int (lbs) % Lbs_per_stn + lbs - int(lbs); pounds = lbs;}// construct Stonewt object from stone, double valuesStonewt::Stonewt(int stn, double lbs){ stone = stn; pds_left = lbs; pounds = stn * Lbs_per_stn +lbs;}Stonewt::Stonewt() // default constructor, wt = 0{ stone = pounds = pds_left = 0;}Stonewt::~Stonewt() // destructor{}// show weight in stonesvoid Stonewt::show_stn() const{ cout << stone << " stone, " << pds_left << " pounds\n";}// show weight in poundsvoid Stonewt::show_lbs() const{ cout << pounds << " pounds\n";}
stone.cpp
// stone.cpp -- user-defined conversions// compile with stonewt.cpp#include <iostream>using std::cout;#include "stonewt.h"void display(const Stonewt & st, int n);int main(){ Stonewt pavarotti = 260; // uses constructor to initialize Stonewt wolfe(285.7); // same as Stonewt wolfe = 285.7; Stonewt taft(21, 8); cout << "The tenor weighed "; pavarotti.show_stn(); cout << "The detective weighed "; wolfe.show_stn(); cout << "The President weighed "; taft.show_lbs(); pavarotti = 265.8; // uses constructor for conversion taft = 325; cout << "After dinner, the tenor weighed "; pavarotti.show_stn(); cout << "After dinner, the President weighed "; taft.show_lbs(); display(taft, 2); cout << "The wrestler weighed even more.\n"; display(422, 2); cout << "No stone left unearned\n"; system("pause"); return 0;}void display(const Stonewt & st, int n){ for (int i = 0; i < n; i++) { cout << "Wow! "; st.show_stn(); }}
7.复数有两个部分组成:实数部分和虚数部分。复数的一种书写方式是:(3.0,4.0)。请定义一个复数类,以便下面的程序可以使用它来获得正确的结果。
(……代码省略……)
注意。必须重载运算符<<和>>。标准C++使用头文件complex提供了比这个示例更广泛的复数支持,因此应将自定义的头文件命名为complex0.h,以免发生冲突。应尽可能使用const。
请注意,经过重载后,cin>>c将提示用户输入实数和虚数部分。
complex0.h
#pragma once#include<iostream>#ifndef COM0_H_using namespace std;class complex { double a; double b;public: complex(); complex(double x, double y); ~complex(); complex operator+(const complex & t) const; complex operator-(const complex & t) const; friend complex operator*(const complex & t,double n);//Êý³Ë friend complex operator*(const complex & t1, const complex & t2); friend complex operator~(const complex & t); friend ostream & operator<<(ostream & os, const complex & c); friend istream & operator >> (istream &in, complex &c);};#endif // !COM0_H_
complex0.cpp
#include "complex0.h"#include<iostream>complex::complex() { a = 0; b = 0;}complex::complex(double x, double y) { a = x; b = y;}complex::~complex() {}complex complex::operator+(const complex & t) const{ complex sum; sum.a = a + t.a; sum.b = b + t.b; return sum;}complex complex::operator-(const complex & t) const{ complex diff; diff.a = a - t.a; diff.b = b - t.b; return diff;}complex operator*(const complex & t, double n) //Êý³Ë{ return complex((t.a)*n, (t.b)*n);} complex operator*(const complex & t1, const complex & t2){ return complex((t1.a*t2.a - t1.b*t2.b), (t1.a*t2.b + t1.b*t2.a));}complex operator~(const complex & t){ return complex(t.a, (-1.0)*t.b);}ostream & operator<<(ostream & os, const complex & c){ os << "(" << c.a << "," << c.b << "!" << ")"; return os;}istream & operator >> (istream &in, complex &c){ in >> c.a >> c.b; return in;}
备注:
操作系统:Windows 10 x64(1803)
编译器:Microsoft Visual Studio 2015