C++ Primer Plus 第6版 第11章 编程练习答案

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

// 类描述中包含两种形式,设计这个类时,将使得用户修改了矢量的一种表示后,对象将自动更新另一种表示。
// 使对象拥有这种智能,使C++类的一个优点
// vector.h
#ifndef VECTOR_H_
#define VECTOR_H_
#include <iostream>
namespace VECTOR {
	class Vector {
	public:
		// RECT表示直角坐标系,POL表示极坐标系
		// 注意:状态成员,标识符POL的作用域为类
		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; }  // 获取x值
		double yval() const { return y; }  // 获取y值
		double magval() const { return mag; }
		double angval() const { return ang; }
		void polar_mode();    // 将mode设置为POL
		void rect_mode();     // 将mode设置为RECT
		// 运算符重载
		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 // !VECTOR_H_
// vector.cpp
#include <cmath>
#include "vector.h"
using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;
using std::cout;

namespace VECTOR {
	const double Rad_to_deg = 45.0 / atan(1.0);   // 该值大约为57.2957795130823
	
	// private methods
	void Vector::set_mag() {
		mag = sqrt(x * x + y * y);
	}
	void Vector::set_ang() {
		if (x == 0 && y == 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);
	}

	// public methods
	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 reset() -- ";
			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 << ", " << v.ang * Rad_to_deg << " )";
		else
			os << "Vector object mode is invalid";
		return os;
	}
}
// 11-1
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <ctime>
#include "vector.h"
int main() {
	using namespace std;
	using VECTOR::Vector;
	ofstream fout;
	fout.open("thewalk.txt");
	srand(time(0));    // time(0)获取当前时间的秒数,srand()设置随机数种子
	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;
		fout << "Target Distance: " << target << ", Step Size: " << dstep << endl;
		fout << steps << ": (x, y) = (0, 0)\n";
		while (result.magval() < target) {
			direction = rand() % 360;    // 随机找方向
			step.reset(dstep, direction, Vector::POL);
			result = result + step; 
			steps++;
			fout << steps << ": (x, y) = (" << result.xval() << ", " << result.yval() << ")\n";
		}
		fout << "After " << steps << " steps, the subject has the following location:\n";
		fout << result << endl;
		result.polar_mode();
		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;
	return 0;
}

thewalk.txt文件中的内容:

Target Dist

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值