c++ primer plus第十章習題答案

第一題到第八題已經補全,但是第八題個人理解按照題上的說法做,即函數指針,沒有什麼意義。也有可能是我沒有理解清楚題意吧。我想明白後會回來再做修改,也希望各位能提一些意見一起探討!


第一題

count.h

//***************************************************************************************//
//*****************************************count.h***************************************//
#ifndef COUNT_H_
#define COUNT_H_

#include <string>

class BankCount
{
private:
	std::string m_name;
	double m_countNum;
	double m_deposit;
public:
	BankCount();
	BankCount(const std::string &co, double recvCountNum = 0, double recvDeposit = 0);
	~BankCount();
	void addr();
	void input(const double store);
	void output(const double expense);
	void display() const;	// promises not to change invoking object
};


#endif
//***************************************************************************************//

count.cpp

#include <iostream>
#include <iomanip>
#include "count.h"

BankCount::BankCount()		// default constructor
{
	std::cout << "Default constructor called.\n";
	m_name = "NULL";
	m_countNum = 0;
	m_deposit = 0;
}

BankCount::BankCount(const std::string &co, double countNum, double deposit)
{
	std::cout << "Constructor using " << co << " called.\n";
	m_name = co;
	m_countNum = countNum;
	if(deposit < 0)//--------------------------string object duplicate?????????????????
	{
		std::cout << "Initial deposit money can not be negative."
			<<" Deposit money is set to 0.\n\n";
		m_deposit = 0;
	}
	else
	{
		m_deposit = deposit;
	}
}

BankCount::~BankCount()
{
	std::cout << "Bye!\n";
}

void BankCount::addr(void)
{
	std::cout << (void *)&m_name << "\n";
}

void BankCount::input(const double store)
{
	if(store < 0)
	{
		std::cout << "Number of storing money can not be negative.\n\n";
	}
	else
	{
		m_deposit = m_deposit + store;
		std::cout << "$" << store << " is stored.\n\n";
	}
}

void BankCount::output(const double expense)
{
	if(expense <= 0)
	{
		std::cout << "Number of expensed money can not be negative.\n\n";
	}
	else
	{
		if(expense - m_deposit)
		{
			std::cout << "Number of expensing money exceeds deposit money.\n"
				<< "Deposit money is $" << m_deposit << ".\n\n";
		}
		else
		{
			m_deposit = m_deposit - expense;
			std::cout << "$" << expense << " is expensed.\n\n";
		}
	}
}

void BankCount::display() const
{
	using namespace std;
	std::cout << m_name << ": \n";
	std::cout << setprecision(20) << "Count number: " << m_countNum << ".\n";
	std::cout << "Deposit money: $" << m_deposit << ",\n\n";
}


main.cpp

#include <iostream>
#include <stdlib.h>
#include "count.h"

int main()
{
	double moneyinput,moneyoutput;
	int execute = 0;
	std::string a = "Mark Wall";
	BankCount member1(a, 1001001101001100, 30000);

	std::cout << (void *)&a << "\n";
	member1.addr();

	member1.display();
	
	while(execute != 4)
	{
		std::cout << "Choose the option:\n"
			<< "1. Enter the number of money you want to store: \n"
			<< "2. Enter the number of money you want to expense:; \n"
			<< "3. Display your count.\n"
			<< "4. Quit.\n";
		std::cin >> execute;
		switch(execute)
		{
			case 1:
				std::cout << "Enter the money: ";
				std::cin >> moneyinput;
				member1.input(moneyinput);
				break;
			case 2:
				std::cout << "Enter the money: ";
				std::cin >> moneyoutput;
				member1.output(moneyoutput);
				break;
			case 3:
				member1.display();
				break;
			case 4:
				break;
			default:
				std::cout << "Wrong choose!\n";
		}
	}

	return 0;
}


第二題

person.h

//*************************************************************************//
//**********************************person.h*******************************//
#ifndef PERSON_H_
#define PERSON_H_

#include <string>

class Person
{
private:
	static const int LIMIT = 25;
	std::string lname;		// Person's last name
	char fname[LIMIT];	// Person's first name
public:
	Person() {lname = ""; fname[0] = '\0';}	// #1
	Person(const std::string & ln, const char * fn = "Heyyou");	// #2
	~Person();
	// the following methods display lname and fname
	void Show() const;			// firstname lastname format
	void FormalShow() const;	// lastname, firstname format
	void Addr() const;
};



#endif
//*************************************************************************//

person.cpp

#include <iostream>
#include <cstring>
#include "person.h"

Person::Person(const std::string & ln, const char * fn)
{
	int str;
	lname = ln;
	str = strlen(fn);
	std::cout << "length of first name: " << str << std::endl;
	strncpy(fname, fn, str+1);
}

Person::~Person()
{
	std::cout << "Bye\n";
}

void Person::Show(void) const
{
	std::cout << fname << " " << lname << "\n";
}

void Person::FormalShow(void) const
{
	std::cout << lname << " " << fname << "\n";
}

void Person::Addr(void) const
{
	std::cout << "Address of char is " << (void *)fname << ". This address is the address of string\n";
	std::cout << "Address of string class is " << &lname << ". This address is not the address of string\n";
	//std::cout <<  << std::endl;  //how to output the address of string in the class string?
}

main.cpp

#include <iostream>
#include <string>
#include "person.h"

using namespace std;

int main()
{
	Person one;						// use default constructor
	Person two("Smythecraft");		// use #2 with one default argument
	Person three("Dimwiddy", "Sam");// use #2, no defaults
	cout << endl;

	cout << "Address of two's \"Smythecraft\" is " 
		<< (void *)"Smythecraft" 
		<< endl << endl;;
	
	one = two;
	one.Show();
	one.FormalShow();
	one.Addr();
	cout << endl;

	one = Person();

	two.Show();
	two.FormalShow();
	two.Addr();
	cout << endl;

	three.Show();
	three.FormalShow();
	three.Addr();
	cout << endl;
	
	return 0;
}


第三題

golf.h

//*****************************************************************//
//*******************************golf.h****************************//
// golf.h -- for pe9-1.cpp
#ifndef GOLF_H_
#define GOLF_H_


class Golf
{
private:
	static const int LEN = 40;
	char m_fullname[LEN];
	int m_handicap;
public:
	// non-interactive version:
	// function sets golf structure to provided name, handicap
	// using values passed as arguments to the function
	Golf() {m_fullname[0] = '\0'; m_handicap = 0;}
	Golf(const char * name, const int hc);
	~Golf();
	// interactive version:
	// fuction solicits name and handicap from user
	// and sets the members of g to the values entered
	// returns 1 if name is entered, 0 if name is empty string
	Golf setgolf();
	// function resets handicap to new value
	void handicap(int hc);

	// function displays contents of golf structure
	void showgolf() const;
};



#endif
//*****************************************************************//

golf.cpp

#include <iostream>
#include <cstring>
#include "golf.h"

extern int ret;

Golf::Golf(const char * name, const int hc)
{
	strcpy_s(m_fullname, name);
	m_handicap = hc;
}

Golf::~Golf()
{
	//
}

Golf Golf::setgolf(void)
{
	using namespace std;
	char fullname[40];
	int handicap;

	cout << "Enter fullname less than 40 words:" << endl;
	cin.getline(fullname,40);

	if(fullname[0] == '\0')
		ret = 0;
	else
	{
		cout << "Enter handicap:" << endl;
		cin >> handicap;
		cin.get();

		*this = Golf(fullname, handicap);
	}

	return *this;
}

void Golf::handicap(int hc)
{
	m_handicap = hc;
}

void Golf::showgolf(void) const
{
	using namespace std;
	cout << "fullname: " << m_fullname << endl;
	cout << "handicap: " << m_handicap << endl;
}

main.cpp

#include <iostream>
#include "golf.h"

int ret = 1;

int main()
{
	Golf ann[10];
	int count = 0;
	do{
		if(count%2 == 0)
		{
			ann[count] = ann[count].setgolf();
		}
		else
		{
			using namespace std;
			char temp[40];
			int num;
			cout << "Enter fullname less than 40 words:" << endl;
			cin.getline(temp,40);
			if(temp[0] == '\0')
			{
				break;
			}
			else
			{
				//
			}
			cout << "Enter handicap:" << endl;
			cin >> num;
			cin.get();
			ann[count] = Golf(temp, num);
		}
		count ++;
	}while((ret == 1)&&(count < 10));

	ann[0].showgolf();
	ann[0].handicap(6);
	ann[0].showgolf();

	return 0;
}


第四題

sales.h

//***********************************************//
//*******************sales.h*********************//
#ifndef SALES_H_
#define SALES_H

namespace SALES
{
	class Sales
	{
	private:
		static const int QUARTERS = 4;
		double sales[QUARTERS];
		double average;
		double max;
		double min;
		void findaver(int n);
		void findmax(int n);
		void findmin(int n);
	public:
	// copies the lesser of 4 or n items from the array ar
	// to the sales member of s and computes and stores the
	// average, maximum, and minimum values of the entered items;
	// remaining elements of sales, if any, set to 0
		Sales() {sales[0] = '\0'; average = 0; max = 0; min = 0;}
		Sales(const double ar[], int n);
		~Sales(){}
		// gathers sales for 4 quarters interactively, stores them
		// in the sales member of s and computes and stores the
		// average, maximum, and minimum values
		Sales setSales();
		// display all information in structure s
		void showSales() const;
	};
}


#endif SALES_H_
//***********************************************//

sales.cpp

#include <iostream>
#include <stdlib.h>
#include "sales.h"

namespace SALES
{
	Sales::Sales(const double ar[], int n)
	{
		using std::cout;
		if(n > 4 || n < 0)
		{
			cout << "error! n is out of range.\n";
			_exit(-1);			// force to quit the whole program
		}						// exit(0),exit(non-0),_exit(0),_exit(non-0) is different from each other.
		else					// _exit(): loss the data in the buffer, exit(): hold the data in the buffer
		{						// exit(0): quit normally, exit(non-0): quit abnormally
			for(int i = 0; i < n; i++)
				sales[i] = ar[i];

			findaver(n);
			findmax(n);
			findmin(n);
			
			for(int i = 0; i < 4; i++)
				sales[i] = 0;
		}
	}

	Sales Sales::setSales(void)
	{
		using std::cout;
		using std::cin;

		int n;
		double temp[4];
		cout << "Set the sales number no more than 4: ";
		cin >> n;
		if(n > 4 || n < 0)
		{
			cout << "error! n is out of range.\n";
			_exit(-1);
		}
		else
		{
			for(int i = 0; i < n; i++)
			{
				cout << "input the #" << i+1 << " sale: ";
				cin >> temp[i];
			}
			*this = Sales(temp, n);	
			return *this;
		}
	}

	void Sales::findaver(int n)
	{
		double total = 0;
		for(int i = 0; i < n; i++)
		{
			total = total + sales[i];
		}
		average = total / n;
	}

	void Sales::findmax(int n)
	{
		max = sales[0];	// initialize max and min, compare with each one
			
		for(int i = 0; i < n; i++)
		{	
			if(sales[i] > max)
				max = sales[i];
		}
	}

	void Sales::findmin(int n)
	{
		min = sales[0];
		for(int i = 0; i < n; i++)
		{
			if(sales[i] < min)
				min = sales[i];
		}
	}

	void Sales::showSales() const
	{
		using std::cout;
		using std::endl;
		cout << endl << endl;;
		cout << "average of sale is " << average << endl;
		cout << "max value of sale is " << max << endl;
		cout << "min value of sale is " << min << endl;
	}
}

main.cpp

#include "sales.h"
using namespace SALES;

int main()
{
	double a[] = {3,4,5,6};
	Sales obj1(a, 4), obj2;
	obj2 = obj2.setSales();
	obj1.showSales();
	obj2.showSales();
	return 0;
}

第五題

stack.h

//**********************************************************************//
//*********************************stack.h******************************//
#ifndef STACK_H_
#define STACK_H_

typedef struct
{
	char fullname[35];
	double payment;
}customer;


class Stack
{
private:
	static const int MAX = 10;	//constant specific to class
	customer m_items[MAX];		// holds stack items
	int m_top;					// index for top stack item
	double m_gloss;		// store total value
public:
	Stack();
	~Stack();
	bool isempty() const;
	bool isfull() const;
	// push() returns false if stack already is full, true otherwise
	bool push(const customer & obj);	// add item to stack
	// pop() returns false if stack already is empty, true otherwise
	bool pop(customer & obj);			// pop top into item
	void show() const;					// show payment

};

#endif
//**********************************************************************//

stack.cpp

#include <iostream>
#include <cstring>
#include "stack.h"

Stack::Stack()
{
	m_top = 0;
	m_gloss = 0;
}

Stack::~Stack()
{
	//
}

bool Stack::isempty(void) const
{
	return (m_top == 0);
}

bool Stack::isfull(void) const
{
	return (m_top == MAX);
}

bool Stack::push(const customer & obj)
{
	if(m_top < MAX)
	{
		m_items[m_top].payment = obj.payment;
		int str;			// statement can be put in wherever but before being used
		str = strlen(obj.fullname);
		strncpy_s(m_items[m_top].fullname, obj.fullname, str+1);
		m_top++;
		return true;
	}
	else
		return false;
}

bool Stack::pop(customer & obj)
{
	if(m_top > 0)
	{
		int str;
		m_top--;
		m_gloss = m_gloss + m_items[m_top].payment;// add the value of payment to gloss
		obj.payment = m_items[m_top].payment;
		str = strlen(m_items[m_top].fullname);
		strncpy_s(obj.fullname, m_items[m_top].fullname, str+1);
		return true;
	}
	else
		return false;
}


void Stack::show(void) const
{
	std::cout << "\n" << "Now " << m_top << " elements are in stack.\n"
		<< "The point \"top\" is pointing to " << m_top << ".\n"
		<< "The total number of payment is " << m_gloss << "\n";
}

main.cpp

#include <iostream>
#include "stack.h"

void showobj(customer obj, int n)
{
	std::cout << "#" << n+1 << ": " << obj.fullname << ": " << obj.payment << "\n";
}

int main()
{
	Stack obj_stack;
	customer recv[11] = {};				// 初始化
	customer object[11] = {				// 如果不初始化,每個元素裏將有隨機值,輸出亂碼
		{"Adobe Reader", 1.1},			// 初始化後如果某位或幾位爲缺省,則對應元素爲0
		{"Microsoft Office", 2.2},
		{"Photo Shop", 3.3},
		{"Surface Pro", 4.4},
		{"Google Chrome", 5.5},
		{"Quartus II", 6.6},
		{"Daemon Tools", 7.7},
		{"VM Ware", 8.8},
		{"TuneUp", 9.9},
		{"Sketch Up", 10},
		{"Whatever", 11.11}
	};
	for(int i = 0; i < 11; i++)
		showobj(object[i], i);			// 輸出將要壓入棧的元素
	obj_stack.show();					// 輸出此時棧的情況
	
	while(!obj_stack.isfull())
	{
		static int j = 0;
		while(!obj_stack.push(object[j]))	// 壓棧,如果成功將不執行while語句
		{									// 應該不會出現失敗的情況,
			std::cout << "Unknown push error!\n";// 之所以這樣寫是處於個人習慣
			_exit(1);
		}
		j++;
	}
	obj_stack.show();

	while(!obj_stack.isempty())				// 出棧,原理同上
	{
		static int k = 0;
		while(!obj_stack.pop(recv[k]))
		{
			std::cout << "Unknown pop error!\n";
			_exit(1);
		}
		k++;
	}
	obj_stack.show();						// 輸出此時棧的情況
	std::cout << std::endl;

	for(int i = 0; i < 11; i++)
		showobj(recv[i], i);				// 輸出接收器接收的數據

	return 0;
}


第六題

move.h

//****************************************************************************//
//**********************************move.h************************************//
#ifndef MOVE_H_
#define MOVE_H_

class Move
{
private:
	double x;
	double y;
public:
	Move(double a = 0, double b = 0);		// sets x, y to a, b
	~Move() {}
	void showmove() const;						// shows current x, y values
	Move add(const Move & m) const;
	// this function adds x of m to x of invoking object to get new x,
	// adds y of m to y of invoking object to get new y, creates a new
	// move object initialized to new x, y values and returns it
	void reset(double a = 0, double b = 0);		// resets x, y to a, b
};


#endif
//****************************************************************************//

move.cpp

#include <iostream>
#include "move.h"

Move::Move(double a, double b)
{
	x = a;
	y = b;
}

void Move::showmove(void) const
{
	std::cout << "current x = " << x << "\n"
		<< "current y = " << y << "\n\n";
}

Move Move::add(const Move & m) const
{
	double xt = x + m.x;
	double yt = y + m.y;
	return (Move(xt, yt));
}

void Move::reset(double a, double b)
{
	x = a;
	y = b;
}

main.cpp

#include <iostream>
#include "move.h"

int main()
{
	Move obj1;
	Move obj2(1.1, 2.2);
	Move obj3 = Move(3.3, 4.4);

	std::cout << "object1:\n";
	obj1.showmove();
	std::cout << "object2:\n";
	obj2.showmove();
	std::cout << "object3:\n";
	obj3.showmove();

	std::cout << "after 1st addition, object3:\n";
	obj3 = obj1.add(obj2);
	obj3.showmove();
	std::cout << "after 2nd addition, object3:\n";
	obj3 = obj3.add(obj2);				// 合法,等號右邊創建臨時對象,沒有修改obj3,
	obj3.showmove();					// 把臨時對象賦給obj3,這時obj3已經不是const
	std::cout << "after reset, object3:\n";
	obj3.reset(1, 1);
	obj3.showmove();

	return 0;
}


第七題

plorg.h

//**************************************************************************//
//*********************************plorg************************************//
#ifndef PLORG_H_
#define PLORG_H_

class Plorg
{
private:
	enum {MAX = 20};
	char m_name[MAX];
	int m_CI;
public:
	Plorg();
	Plorg(char * s);
	~Plorg() {}
	void changeCI(int temp);
	void show() const;
};


#endif
//**************************************************************************//

plorg.cpp

#include <iostream>
#include <cstring>
#include "plorg.h"

Plorg::Plorg()
{
	strcpy(m_name, "Plorga");
	m_CI = 50;
}

Plorg::Plorg(char * s)
{
	int str = strlen(s);
	//strncpy_s(m_name, 20, s, str+1);
	strncpy_s(m_name, s, str+1);// 與上一句等效,拷貝19和str中較小的字符數,在結尾處加'\0'
								// 實際測試中發現拷貝字符數多於19個時強制退出並報錯
	m_CI = 50;
}

void Plorg::changeCI(int temp)
{
	m_CI = temp;
}

void Plorg::show(void) const
{
	std::cout << "plorg name: " << m_name << "\n"
		<< "plorg CI: " << m_CI << "\n";
}

main.cpp

#include <iostream>
#include <string>
#include "plorg.h"

int main()
{
	using namespace std;
	//char na[24]= "asdfasdfasdfasdfasdfas";
	string name;
	Plorg obj1;
	Plorg obj2("Betelgeusean");

	cout << "object1:\n";
	obj1.show();
	cout << "object2:\n";
	obj2.show();

	cout << "Enter the name of object1 less than 20 words: ";
	getline(cin, name);
	Plorg obj3((char *)name.c_str());	// name是string類的對象,字符串地址需要通過方法c_str得到
	//Plorg obj3(na);					// 直接對name取址得到的是對象地址
	obj3.show();

	obj2.changeCI(60);
	cout << "object2:\n";
	obj2.show();

	return 0;
}


第八題

list.h

//********************************************************************************//
//************************************list.h**************************************//
#ifndef LIST_H_
#define LIST_H_

typedef int Item;// 默認Item爲int型,可以換爲其他基本數據類型,不能爲結構體
//typedef double Item;
//typedef float Item;
//typedef short Item;
//typedef char Item;

void show(Item &);

class List
{
private:
	void * m_pt;// 設置成空指針是爲了能夠指向任意類型的數據
	int m_pos;	// 標記表示當前存儲數據的位置,實際上是數組中下一個爲空的位置,類似於棧
	int m_MAX;	// 存儲列表可容納的數據個數
public:
	List();
	List(const int n);
	~List();
	bool isempty() const;
	bool isfull() const;
	bool add(const Item &);
	void visit(void (*pt)(Item &)) const;
};


#endif
//********************************************************************************//

list.cpp

#include <iostream>
#include "list.h"

List::List()
{
	//m_pt = new int [1];		// 只有一個int型0元素的列表
	//*(int *)m_pt = 0;
	//m_MAX = 1;
	//m_pos = 1;
	m_pt = NULL;				// 指針指向空,空列表
	m_pos = 0;
	m_MAX = 0;
}

List::List(const int n)
{
	m_pt = new Item [n];
	m_pos = 0;
	m_MAX = n;
	(Item *)m_pt;
}

List::~List()
{
	delete [] m_pt;				// 在析構函數裏要把m_pt指針指向的空間釋放
}

bool List::isempty(void) const
{
	return (m_pos == 0);
}

bool List::isfull(void) const
{
	return (m_pos == m_MAX);
}

bool List::add(const Item & item)
{
	if(isfull())
		return false;
	else
	{
		*((Item *)m_pt+(m_pos++)) = item;// 強制轉換m_pt指向的數據類型,後面加偏移地址
		return true;
	}
}

void List::visit(void (*pt)(Item &)) const	// 該函數隱式訪問類內數據,接收函數指針爲參數
{
	int flag = 0;	// 標記沒有找到數據
	Item item;		// item是函數指針指向的函數的參數,要在visit內聲明
	std::cout << "Enter the element you want to visit: ";
	std::cin >> item;
	for(int i = 0; i < m_pos; i++)
	{
		if(item == *((Item *)m_pt+i))// 左值,要找的參數;右值,列表中的數據
		{
			std::cout << "Find " << item << " in position " << i+1 << std::endl;
			(*pt)(item);
			flag++;
		}
	}
	if(flag == 0)
		std::cout << "No such item has been found!\n";
}

void show(Item & item)	// 這個函數有什麼意義我還沒有想明白,莫非只是爲了展示一下
{						// 函數指針技術?弄清楚後會回來補充
	std::cout << item << "\n";
}

main.cpp

#include <iostream>
#include "list.h"

int main()
{
	using std::cout;
	using std::cin;
	List Tlist(5);// 可以交互式輸入列表容量,爲了簡單直接給5
	Item temp;
	int option = 0;

	while(option != 5)
	{
		cout << "choose the option:\n";
		cout << "1. check if the list is empty.\n"
			<< "2. check if the list is full.\n"
			<< "3. add element to the list.\n"
			<< "4. visit a element.\n"
			<< "5. quit.\n";
		cin >> option;
		switch(option)
		{
		case 1:
			if(Tlist.isempty())		// 檢查是否爲空
				cout << "The list is empty.\n";
			else
				cout << "The list is not empty.\n";
			break;
		case 2:
			if(Tlist.isfull())		// 檢查是否爲滿
				cout << "The list is full.\n";
			else
				cout << "The list is not full.\n";
			break;
		case 3:
			if(!Tlist.isfull())		// 不爲空時可以添加數據
			{
				cout << "Enter the item you want to add in: ";
				cin >> temp;
				if(Tlist.add(temp))
					cout << "Add operation Succeed!\n";
				else
					cout << "Add operation fail!\n";
			}
			else
				cout << "The list is already full!\n";
			break;
		case 4:						// 查找元素
			if(!Tlist.isempty())
				Tlist.visit(show);
			else
				cout << "The list is empty, no element exists!\n";
			break;
		case 5:
			break;
		default:
			cout << "Entered the wrong number, please enter again: ";
		}
		cout << std::endl;
	}

	cout << "Bye!\n";

	return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章