首页 > 编程语言 >C++Primer Plus第十一章类的使用,课后练习1,还是醉汉回家的故事

C++Primer Plus第十一章类的使用,课后练习1,还是醉汉回家的故事

时间:2024-06-01 18:29:19浏览次数:14  
标签:set const cout double C++ Vector Plus mode 课后练习

编程练习11.9
1.修改程序清单 11.5,使之将一系列连续的随机漫步者位置写入到文件中。对于每个位置,用步号进行标示。另外,让该程序将初始条件(目标距离和步长)以及结果小结写入到该文件中。该文件的内容与下面类似:
Target Distance:100,stepSize:20
0:(xy)=(0,0)
1:(x,y)=(-11.4715,16.383)
2:(x,y)=(-8.68807,-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 perstep=3.97081

vector.h

#pragma once
//vect.h -- Vector class with <<,mode state
#ifndef	VECTOR_H_	
#define VECTOR_H_

#include<iostream>
namespace VECTOR
{
	class Vector
	{
	public:
		enum Mode { RECT, POL };//以此为直角坐标,极坐标(长度,角度)
		//RECT for rectangular,POL for Polar modes
	private:
		double x;//horizontal value x方向x坐标
		double y;//vertical value  y方向y坐标
		double mag; //length of value  极坐标的长度
		double ang;//direction of vector in degrees,极坐标的角度
		Mode mode;//RECT or POL
		//private methods for setting values
		void set_mag();
		void set_ang();
		void set_x();
		void set_y();
	public:
		Vector();
		Vector(double x, double y, Mode form = RECT);
		void reset(double x, double y, Mode form = RECT);
		~Vector();
		double xval()const { return x; }//report x val
		double yval()const { return y; }//report y val
		double magVal()const { return mag; }//report magnitude
		double angval()const { return ang; }//report angle
		void polar_mode();//set mode to POL
		void rect_mode();//set mode to RECT
		//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 Vector
}//end namespace VECTOR

#endif

vetor.cpp

//vect.cpp == methods for the Vector class
#include<cmath>	
#include"vector.h" //includes<iostream>
using std::sqrt;
using std::sin;
using std::cos;
using std::atan;
using std::atan2;
using std::cout;
using std::endl;

namespace VECTOR
{
	//comput degrees in one radian 
	const double Rad_to_deg = 45.0 / atan(1.0);
	//should be about 57.2957795130823

	//private methods
	//calculates magnitude from x and y 
	void Vector::set_mag()
	{
		mag = sqrt(x * x + y * y);
	}
	void Vector::set_ang()
	{
		if (x == 0.0 && y == 0.0)
		{
			ang = 0.0;
		}
		else
		{
			ang = atan2(y, x);
		}
	}
	//set x from polar coorinate 
	void Vector::set_x()
	{
		x = mag * cos(ang);
	}
	//set y from polar coorinate
	void Vector::set_y()
	{
		y = mag * sin(ang);
	}
	//public methods 
	//default constructor
	Vector::Vector()
	{
		y = x = mag = ang = 0.0;
		mode = RECT;
	}

	//construct vector from rectangular coordinates if form is r 
	//(the default) or else from polay coordinates if form is p
	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_mag();
			set_ang();
		}
		else
		{
			cout << "Incorrect 3rd argument to Vector() -- ";
			cout << "vector set to 0\n";
			x = y = mag = ang = 0.0;
			mode = RECT;
		}
	}
	//reset vector from rectangular coorinates if form is 
	//RECT(the default) or else from polar coorinates if 
	//form is POL
	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 Vector() -- ";
			cout << "vector set to 0\n";
			x = y = mag = ang = 0.0;
			mode = RECT;
		}
	}
	Vector::~Vector()//destructor
	{

	}

	void Vector::polar_mode()//set to polay mode 
	{
		mode = POL;
	}

	void Vector::rect_mode() // set to rectangular mode
	{
		mode = RECT;
	}

	//operator overloading 
	//add two Vectors 
	Vector Vector::operator+(const Vector& b)const
	{
		return Vector(x + b.x, y + b.y);
	}
	//sub 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);
	}

	//multyply 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 coorinates if mode is RECT
	//else display polar coordinates if mode is 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.mag << ", " << v.ang * Rad_to_deg << ")";
		}
		else
			os << "Vector object mode is invalid";
		return os;
	}
}//end namespace VECTOR

main.cpp

#if 1
#include <iostream>
#include<cstdlib>	//rand,srand() prototypes
#include<ctime>//time()prototype
#include<fstream>
#include"vector.h"
int main()
{
	using namespace std;
	using VECTOR::Vector;
	ofstream of;
	of.open("ofoutput.txt");
	srand(time(0));//seed random-number generator 
	double direction;
	Vector step;
	Vector result(0.0, 0.0);
	unsigned long steps = 0;
	double target;
	double dstep;
	cout.setf(ios_base::fixed, ios_base::floatfield);
	cout.precision(2);
	of.setf(ios_base::fixed, ios_base::floatfield);
	of.precision(2);
	cout << "Enter target distance(q to quit):";
	of << "Enter target distance(q to quit):";
	while (cin >> target)
	{
		of << target << ", ";
		cout << "Enter step length: ";
		of << "Enter step length: ";
		if (!(cin >> dstep))
		{
			break;
		}
		of << dstep<<endl;
		while (result.magVal() < target)
		{
			cout  << steps << "\t: (x,y) = (" << result.xval()<<"    " << result.yval() << ")" << endl;
			of    << steps << "\t: (x,y) = (" << result.xval() << "    " << result.yval() << ")" << endl;
			direction = rand() % 360;
			step.reset(dstep, direction, Vector::POL);
			result = result + step;
			steps++;
		}
		cout << steps << ": (x,y) = (" << result.xval() << "    " << result.yval() << ")" << endl;
		of   << steps << ": (x,y) = (" << result.xval() << "    " << result.yval() << ")" << endl;
		cout << "After " << steps << " steps,the subject " "has the following location:\n";
		of << "After " << steps << " steps,the subject " "has the following location:\n";
		cout << result << endl;
		of << result << endl;
		result.polar_mode();
		cout << " or\n" << result << endl;
		of << " or\n" << result << endl;
		cout << "Average outward distance per step = "<< result.magVal() / steps << endl;
		of << "Average outward distance per step = " << result.magVal() / steps << endl;
		steps = 0;
		result.reset(0.0, 0.0);
		cout << "Enter target distance(q to quit): ";
		of << "Enter target distance(q to quit): ";
	}
	cout << "Bye!\n";
	cin.clear();
	while (cin.get() != '\n')
	{
		continue;
	}
	cout.unsetf(cout.flags());
	of.unsetf(cout.flags());
	of.close();
	return 0;
}
#endif

实验结果
在这里插入图片描述

总结:
1,在11.5程序清单中已经实现过。
2,增加文件处理的类ofstream,打开文件,关闭文件
3,增加格式化控制cout.setf(ios_base::fixed, ios_base::floatfield);
cout.precision(2);cout.unsetf(cout.flags());
4,这种处理的随机性使得每次运行结果都不同,即使初始条件相同。然而,平均而言,步长减半,步数将为原来的4倍。概率理论表明,平均而言,步数(N)、步长(s),净距离D之间的关系如下:
N=(D/s)的N次方
5,做这种练习锻炼思维为日后编程打下扎实的基础

标签:set,const,cout,double,C++,Vector,Plus,mode,课后练习
From: https://blog.csdn.net/zhyjhacker/article/details/139359847

相关文章

  • 【C++】内存管理
    文章目录1.回顾C/C++的内存管理2.C++内存管理方式2.1new/delete对于内置类型2.2new/delete对于自定义2.3operatornew与operatordelete函数2.4new和delete的实现原理2.5定位new表达式3.常见面试题1.回顾C/C++的内存管理首先,我们来回顾一下内存中的区域划分......
  • 【C/C++】--- 指针详解 2.0
    接下来进入指针的进阶部分,准备好大脑补充:(重点)数组名是数组首元素地址数组首元素地址和数组地址,值相同,但本质不同,区别在于二者的类型不相同比如数组intarr[10];数组首元素地址的类型:首先这是一个地址所以要用指针接收,(),然后是地址指向元素的类型为int,所以这个指针的......
  • macOS下使用bits/stdc++.h万能头文件
     macOS下使用bits/stdc++.h万能头文件1.终端中输入echo|g++-v-xc++-E-#include<...>searchstartshere:/usr/local/include/Library/Developer/CommandLineTools/usr/bin/../include/c++/v1/Library/Developer/CommandLineTools/usr/lib/clang/12.......
  • C++——类
    目录C++类访问权限虚函数1.定义底层实现2.构造函数/析构函数3.抽象类/纯虚函数常见问题1.虚函数不可以声明为inline吗2.构造函数为什么不能为虚函数?3.析构函数为什么可以为虚函数?4.构造函数和析构函数可以调用虚函数吗?5.虚析构函数的作用,父类的析构函数是否要设置为虚......
  • C++生产者消费者模型
    这里模拟了一个队列,5个消费者线程和5个生产者线程来共同使用队列里面的数据处理。包括了阻塞和非阻塞的出队入队方法。注意在添加线程时使用到了std::ref引用,在传参给线程时不能直接传入queue的引用,要使用std::ref才是真正意义上的引用,当直接使用queue编译器是不会通过的,因为其实......
  • C++:最小公倍数与最大公约数
    最大公约数(GreatestCommonDivisor,GCD)最小公倍数(LeastCommonMultiple,LCM)#include<iostream>//函数:计算两个数的最大公约数(GCD),这被称为欧几里得算法intgcd(inta,intb){if(b==0)returna;returngcd(b,a%b);}//函数:计算两个数的......
  • 1-006 连续因子(分数 20,c++)
    一个正整数 N 的因子中可能存在若干连续的数字。例如630可以分解为3×5×6×7,其中5、6、7就是3个连续的数字。给定任一正整数 N,要求编写程序求出最长连续因子的个数,并输出最小的连续因子序列。输入格式:输入在一行中给出一个正整数 N(1<N<231)。输出格式:首先在第1......
  • 【C++进阶】深入STL之string:掌握高效字符串处理的关键
    ......
  • C++ 智能指针学习笔记
    1、为什么使用智能指针?    一句话就是为了防止内存泄漏。voidremodel(std::string&str){std::string*ps=newstd::string(str)...str=ps;return;}    举个例子,如上面代码,每当调用时,该函数都分配堆内的内存,但从不收回,从而导致......
  • C++常用STL容器
    备注:文中图片来自hackingcpp.vectorvector是C++中最常用的容器,它可以动态改变自身大小。dequelist(双向链表)forward_list(单向链表)unordered_setsetunordered_mapmap......