c++.primer.plus第五版第十章编程练习答案
2015-07-23 19:08
603 查看
第一题、复习题5中的类:
BankAccout.h:
BankAccout.cpp为:
小程序演示类的特性:
第二题:
person.h:
person.cpp:
测试程序:main.cpp
第三题:完成第九章的编程练习1,但要用正确的golf类声明替换那里的代码。用带合适参数的构造函数替换setgolf(golf &,const char *,int),以提供初始值。保留setgolf()的交互版本,但要用构造函数来实现它(例如,setgolf()的代码应该获得数据,将数据传递给构造函数来创建一个临时对象,并将其赋给调用对象,即*this).
golf.h:
golf.cpp:
测试程序:main.c
第四题:完成第九章的编程练习4,但将Sales结构相关的函数转换为一个类及其方法。用构造函数替换setSales[sales &,double[],int)函数。用构造函数实现setSales(Sales &)方法的交互版本。将类保留在名称空间SALES中。
第九章第四题:请基于下面这个名称空间编写一个由3个文件组成的程序:
第一个文件是一个头文件,其中包含名称空间。第二个文件是一个源代码文件,它对这个名称空间进行扩展,以提供3个函数的定义。第三个文件声明两个Sales对象,并使用setSales()的交互式版本为一个结构提供值,然后使用setSales()的非交互式版本为另一个结构提供值。另外它是使用showSales()来显示 这两个结构的内容。
sales.h
sales.cpp
测试程序:main.cpp
第五题:考虑下面的结构声明:
static.h:
第六题:
// 下面是一个类声明:
// 请提供成员函数的定义和测试这个类的程序。
move.h:
move.cpp:
测试小程序 main.cpp:
第七题:Betelgeusean plorg有这些特征:
数据:
plorg的名称不超过19个字符。
plorg有满意指数(CI),这是一个整数。
操作:
新的plorg将有名称,其CI值为50。
plorg的CI可以修改。
plorg可以报告它的名称和CI。
plorg的默认名称为"Plorga"。
请编写一个Plorg类声明(包括数据成员和成员函数原型)来表示plorg,并编写成员函数的定义。然后编写一个小程序,以演示Plorg类的所有特性。
betelgeuseanplorg.h:
betelgeuseanplorg.cpp:
第八题:(待做)
可以将简单列表描述成下面这样:
可存储0或多个某种类型的列表。
可创建空列表。
可在列表中添加数据项。
可确定列表是否为空。
可确定列表是否为满。
可访问列表中的每一个数据项,并对它执行某种操作。
可以看到,这个列表确实很简单,例如,它不允许插入或删除数据项。
请设计一个List类来表示这种抽象类型。您应提供头文件list.h和实现文件list.cpp,前者包含类定义,后者包含类方法的实现。您还应创建一个简短的程序来使用这个类。
可以选择使用数组或链表来实现该列表,但公有接口不应该依赖于所做的选择。也就是说,公有接口不应有数组索引、节点指针等。应使用通用概念来表达创建列表、在列表中添加数据项等操作。对于访问数据项以及执行操作,通常应使用将函数指针作为参数的函数来处理:
void visit(void (*pf)(Item &));
其中,pf指向一个将Item引用作为参数的函数(不是成员函数),Item是列表中数据项的类型。visit()函数将该函数用于列表中的每个数据项。
BankAccout.h:
#ifndef _BANKACCOUNT_H #define _BANKACCOUNT_H #include <cstring> // class definition class BankAccount { private: char name[40]; // or std::string name; char acctnum[25]; // or std::string acctnum; double balance; public: BankAccount(const char* client,const char * num,double bal = 0.0); // or BankAccount(const std::string & client,const std::string & num,double bal = 0.0) void show(void)const; void dposit(double cash); void withdraw(double cash); }; #endif
BankAccout.cpp为:
#include <iostream> #include <cstring> #include "BankAccount.h" using std::cout; using std::endl; BankAccount::BankAccount(const char* client,const char * num,double bal) // 定义时参数不用默认值,否则编译不通过 { strncpy(name,client,40); name[39] = '\0'; strncpy(acctnum,num,25); acctnum[24] = '\0'; balance = bal; } // or //BankAccount::BankAccount(const std::string & client,const std::string & num,double bal) //{ // name = client; // acctnum = num; // balance = bal; //} void BankAccount::show(void)const { cout << "Name:\t" << name << endl << "Account:\t" << acctnum << endl << "Balance:\t" << balance << endl; } void BankAccount::dposit(double cash) { balance += cash; } void BankAccount::withdraw(double cash) { if(balance >= cash) balance -= cash; else cout << "no much money!\n"; }
小程序演示类的特性:
#include <iostream> #include "BankAccount.h" using std::cin; using std::cout; using std::endl; int main() { char client[40]; char num[25]; double bal = 0.0; cout << "Please input your name: "; cin.getline(client,40); cout << "Please input your acctnum: "; cin.getline(num,25); cout << "Please input your balance: "; cin >> bal; cout << "Now make a BankAccount constructor!\n"; BankAccount tmp(client,num,bal); int flag = 0; cout << "Please input the flag: "; while(cin >> flag) { if(flag == 0) tmp.show(); else if(flag == 1) { double num; cout << "How much money you want to dposit: "; cin >> num; tmp.dposit(num); } else if(flag == 2) { double num; cout << "How much money you want to withdraw:"; cin >> num; tmp.withdraw(num); } cout << "Please input the flag: "; } return 0; }
第二题:
person.h:
// 2,下面是一个非常简单的类定义: #ifndef PERSON_H_ #define PERSON_H_ #include <cstring> #include <string> using std::string; class Person{ private: static const int LIMIT = 25; string lname; // Person's last name char fname[LIMIT]; // Person's first name public: Person() {lname = ""; fname[0] = '\0';} Person(const string & ln,const char * fn = "Heyyou"); // #2 // the following methods display lname and fname void show()const; // firstname lastname format void FormalShow()const; // lastname,firstname format }; #endif // PERSON_H
person.cpp:
// 2 #include <iostream> #include "person.h" using std::cout; using std::endl; Person::Person(const string & ln,const char * fn) { lname = ln; strncpy(fname,fn,LIMIT); fname[LIMIT - 1] = '\0'; } void Person::show()const { cout << "The name is:\t" << fname << ' ' << lname << endl; } void Person::FormalShow()const { cout << "The name is:\t" << lname << ',' << fname << endl; }
测试程序:main.cpp
// 2 #include <iostream> #include "person.h" using std::cout; using std::endl; int main() { Person one; // use default constructor Person two("Smythecraft"); // use #2 with one default argument Person three("Dimwiddy","Sam"); // use #2,no defaults one.show(); cout << endl; one.FormalShow(); cout << endl; two.show(); cout << endl; two.FormalShow(); cout << endl; three.show(); cout << endl; three.FormalShow(); cout << endl; return 0; }
第三题:完成第九章的编程练习1,但要用正确的golf类声明替换那里的代码。用带合适参数的构造函数替换setgolf(golf &,const char *,int),以提供初始值。保留setgolf()的交互版本,但要用构造函数来实现它(例如,setgolf()的代码应该获得数据,将数据传递给构造函数来创建一个临时对象,并将其赋给调用对象,即*this).
// 第九章编程练习1 /* // 1,下面是一个头文件: // golf.h -- for pe9-1.cpp static const int Len = 40; struct golf { char fullname[Len]; int handicap; }; // non-interactive version: // function sets golf structure to provided name,handicap // using values passed as arguments to the function void setgolf(golf &g,const char *name,int hc); // interactive version: // function 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 int setgolf(golf & g); //交互版本 // function resets handicap to new value_type void handicap(golf & g,int hc); // function displays contents of golf structure void showgolf(const golf & g); setgolf()被重载,可以这样使用其第一个版本: golf ann; setgolf(ann,"Ann Birdfree",24); 上述函数调用提供了存储在Ann结构中的信息。可以这样使用其第二个版本: golf andy; setgolf(andy); 上述函数将提示用户输入姓名和等级,并将它们存储在andy结构中。这个函数可以(但不一定必须)在内部使用第一个版本。根据这个头文件,创建一个多文件程序。其中的一个文件名为golf.cpp,它提供了与头文件中的原型匹配的函数定义;另一个文件应包含main(),并演示原型化函数的所有特性。例如,包含一个让用户输入的循环,并使用输入的数据来填充一个由golf结构组成的数组,数组被填满或用户将高尔夫选手的姓名设置为空字符串时,循环将结束。main()函数只使用头文件中原型化的函数来访问golf结构。 */
golf.h:
#ifndef GOLF_H #define GOLF_H class Golf{ private: static const int Len = 40; char fullname[Len]; int handicap; public: Golf(const char * name = "AAAAA",int hc = 10); ~Golf(); int setGolf(); void sethandicap(int hc); void showGolf()const; }; #endif // GOLF_H
golf.cpp:
#include <iostream> #include <cstring> #include "golf.h" Golf::Golf(const char * name,int hc) { strncpy(fullname,name,40); fullname[39] = '\0'; handicap = hc; } Golf::~Golf() { using std::cout; using std::endl; cout << "Bye!" << endl; } int Golf::setGolf() { using std::cin; using std::cout; using std::endl; char fullname[Len]; int handicap; cout << "Please input the name of the golf player: "; cin.get(fullname,Len); // 读取一行 if(cin) { cout << "Please input the handicap of the golf player: "; cin >> handicap; cin.get(); *this = Golf(fullname,handicap); return 1; } else return 0; } void Golf::sethandicap(int hc) { handicap = hc; } void Golf::showGolf()const { std::cout << "hullname: " << fullname << ", \thandicap: " << handicap << std::endl; }
测试程序:main.c
#include <iostream> #include "golf.h" using std::cin; using std::cout; using std::endl; int main() { Golf one; Golf two; Golf three; one.showGolf(); // 默认构造函数 two.setGolf(); // 交互版本 two.showGolf(); two.sethandicap(2000); //成员函数 two.showGolf(); //成员函数 three.sethandicap(50); three.showGolf(); return 0; }
第四题:完成第九章的编程练习4,但将Sales结构相关的函数转换为一个类及其方法。用构造函数替换setSales[sales &,double[],int)函数。用构造函数实现setSales(Sales &)方法的交互版本。将类保留在名称空间SALES中。
第九章第四题:请基于下面这个名称空间编写一个由3个文件组成的程序:
<span style="color:#ff6600;">namespace SALES { const int QUARTERS = 4; struct Sales { double sales[QUARTERS]; double average; double max; double min; } // 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 void setSales(Sales & s,const double ar[],int n); // gathers sales for 4 quarters interactively,stores them // in the sales member of s and computes and stores the // average,maximum, and minimum values void setSales(Sales & s); // display all information in structure s void showSales(const Sales & s); } </span>
第一个文件是一个头文件,其中包含名称空间。第二个文件是一个源代码文件,它对这个名称空间进行扩展,以提供3个函数的定义。第三个文件声明两个Sales对象,并使用setSales()的交互式版本为一个结构提供值,然后使用setSales()的非交互式版本为另一个结构提供值。另外它是使用showSales()来显示 这两个结构的内容。
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; public: Sales(const double ar[],int n); Sales(); ~Sales(); void showSales(); }; } #endif // SALES_H_
sales.cpp
// 4 对题意的理解可能有问题,这里Sales(const double ar[],int n)的是将ar中前四个或n(n < 4时)复制给sales #include <iostream> #include "sales.h" namespace SALES { using SALES::Sales; using std::cout; using std::endl; using std::cin; Sales::Sales(const double ar[],int n) { max = min = ar[0]; double sum = 0.0; for(int i = 0;i < QUARTERS;i++) { if(i <= n) sales[i] = ar[i]; else sales[i] = 0.0; if(max < sales[i]) max = sales[i]; if(min > sales[i]) min = sales[i]; sum += sales[i]; } average = sum * 1.0 / QUARTERS; } Sales::Sales() { double arr[QUARTERS]; cout << "Please fill the array: \n"; for(int i = 0;i < QUARTERS;i++) { cout << "arr[" << i << "] = "; cin >> arr[i]; } *this = Sales(arr,QUARTERS); } Sales::~Sales() { cout << "Bye!\n"; } void Sales::showSales() { cout << "\n=============================================\n"; for(int i = 0;i < QUARTERS;i++) cout << "sales[" << i << "] = " << sales[i] << endl; cout << "max = " << max << endl; cout << "min = " << min << endl; cout << "average = " << average << endl; cout << "\n=============================================\n"; } }
测试程序:main.cpp
#include <iostream> #include "sales.h" using SALES::Sales; int main() { const int limit = 4; double arr[limit] = {3.4,1.3,0,0}; Sales one(arr,limit); Sales two; one.showSales(); two.showSales(); return 0; }
第五题:考虑下面的结构声明:
struct customer{ char fullname[35]; double payment; };编写一个程序,它从堆栈中添加和删除customer结构(堆栈用Stack类声明表示)。每次customer结构被删除时,其payment的值都被加入到总数中,并报告总数。注意:应该可以直接使用Stack类而不作修改;只需修改typedef声明,使Item的类型为customer,而不是unsigned long即可。
/* // 程序清单10.10 stack.h // stack.h -- class definition for the stack ADT #ifndef STACK_H_ #define STACK_H_ typedef unsigned long Item; class Stack { private: enum {MAX = 10}; // constant specific to class Item items[MAX]; // holds stack items int top; // index for top stack item public: Stack(); bool isempty()const; bool isfull()const; // push()returns false if stack already is full,true otherwise bool push(const Item & item); // add item to stack // pop()returns false if stack already is empty,true otherwise bool pop(Item & item); // pop top into item }; #endif // STACK_H_ */
static.h:
// stack.h // stack.h -- class definition for the stack ADT #ifndef STACK_H_ #define STACK_H_ typedef struct customer { char fullname[35]; double payment; }CUSTOMER; typedef customer Item; class Stack { private: enum {MAX = 10}; // constant specific to class Item items[MAX]; // holds stack items int top; // index for top stack item int total; public: Stack(); ~Stack(); bool isempty()const; bool isfull()const; // push()returns false if stack already is full,true otherwise bool push(const Item & item); // add item to stack // pop()returns false if stack already is empty,true otherwise bool pop(Item & item); // pop top into item }; #endif // STACK_H_static.cpp:
// stack.cpp -- Stack member functions #include <iostream> #include "stack.h" Stack::Stack() // create an empty stack { top = 0; total = 0; } Stack::~Stack() { using std::cout; cout << "Bye!\n"; } bool Stack::isempty()const { return top == 0; } bool Stack::isfull()const { return top == MAX; } bool Stack::push(const Item & item) { if(top < MAX) { items[top++] = item; return true; } else return false; } bool Stack::pop(Item & item) { if(top > 0) { using std::cout; using std::endl; item = items[--top]; total = total + item.payment; cout << "PO#" << item.fullname << endl; cout << "Total = " << total << endl; return true; } else return false; }测试程序:main.cpp
// testing the Stack class #include <iostream> #include <cctype> // or ctype.h #include "stack.h" int main() { using namespace std; Stack st; // create an empty stack char ch; CUSTOMER po; cout << "Please enter A to add a purchase order.\n" << "P to process a PO,or Q to quit.\n"; while(cin >> ch && toupper(ch) != 'Q') { while(cin.get() != '\n') continue; if(!isalpha(ch)) { cout << '\a'; continue; } switch(ch) { case 'A': case 'a': cout << "Enter a PO fullname to add:\t"; cin.getline(po.fullname,35); cout << "Enter a PO payment to add:\t"; cin >> po.payment; if(st.isfull()) cout << "stack already full\n"; else st.push(po); break; case 'P': case 'p':if(st.isempty()) cout << "Stack already empty\n"; else st.pop(po); break; } cout << "Please enter A to add a purchase order,\n" << "P to process a PO, or Q to quit.\n"; } cout << "Bye\n"; return 0; }
第六题:
// 下面是一个类声明:
class Move { private: double x; double y; public: Move(double a = 0,double b = 0); // sets x,y to a,b 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); // reset x,y to a,b };
// 请提供成员函数的定义和测试这个类的程序。
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 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); // reset x,y to a,b }; #endif // _MOVE_H_ // 请提供成员函数的定义和测试这个类的程序。
move.cpp:
#include <iostream> #include "move.h" Move::Move(double a,double b) { x = a; y = b; } void Move::showmove()const { using std::cout; using std::endl; cout << "=============================\n"; cout << "x = " << x << endl; cout << "y = " << y << endl; cout << "=============================\n"; } Move Move::add(const Move & m)const { return Move(x + m.x,y + m.y); } void Move::reset(double a,double b) { x = a; y = b; }
测试小程序 main.cpp:
#include <iostream> #include "move.h" int main() { Move one; Move two(3,3); one.showmove(); two.showmove(); one = one.add(two); one.showmove(); one.reset(1,1); one.showmove(); return 0; }
第七题:Betelgeusean plorg有这些特征:
数据:
plorg的名称不超过19个字符。
plorg有满意指数(CI),这是一个整数。
操作:
新的plorg将有名称,其CI值为50。
plorg的CI可以修改。
plorg可以报告它的名称和CI。
plorg的默认名称为"Plorga"。
请编写一个Plorg类声明(包括数据成员和成员函数原型)来表示plorg,并编写成员函数的定义。然后编写一个小程序,以演示Plorg类的所有特性。
betelgeuseanplorg.h:
#ifndef _BETELGEUSEANPLORG_H_ #define _BETELGEUSEANPLORG_H_ class Bplorg { private: enum {MAX = 20}; char name[MAX]; unsigned int CI; public: Bplorg(const char *nm = "Plorga",int numci = 50); // 默认参数CI=50 默认名称为Plorga ~Bplorg(); void setCI(int numci); // 修改CI值 void showBplorg()const; // 报告它的名称和CI }; #endif // _BETELGEUSEANPLORG_H_
betelgeuseanplorg.cpp:
#include <iostream> #include <cstring> #include "betelgeuseanplorg.h" Bplorg::Bplorg(const char *nm,int numci) // 默认参数CI=50 默认名称为Plorga { strncpy(name,nm,19); name[19] = '\0'; CI = numci; } Bplorg::~Bplorg() { using std::cout; using std::endl; cout << "Bye" << endl; } void Bplorg::setCI(int numci) // 修改CI值 { CI = numci; } void Bplorg::showBplorg()const // 报告它的名称和CI { using std::cout; using std::endl; cout << "Name:\t" << name << "\nCI:\t" << CI << endl; }测试小程序:main.cpp:
#include <iostream> #include "betelgeuseanplorg.h" int main() { Bplorg one; Bplorg two("two two two",20); one.showBplorg(); one.setCI(10); one.showBplorg(); two.showBplorg(); two.setCI(15); two.showBplorg(); return 0; }
第八题:(待做)
可以将简单列表描述成下面这样:
可存储0或多个某种类型的列表。
可创建空列表。
可在列表中添加数据项。
可确定列表是否为空。
可确定列表是否为满。
可访问列表中的每一个数据项,并对它执行某种操作。
可以看到,这个列表确实很简单,例如,它不允许插入或删除数据项。
请设计一个List类来表示这种抽象类型。您应提供头文件list.h和实现文件list.cpp,前者包含类定义,后者包含类方法的实现。您还应创建一个简短的程序来使用这个类。
可以选择使用数组或链表来实现该列表,但公有接口不应该依赖于所做的选择。也就是说,公有接口不应有数组索引、节点指针等。应使用通用概念来表达创建列表、在列表中添加数据项等操作。对于访问数据项以及执行操作,通常应使用将函数指针作为参数的函数来处理:
void visit(void (*pf)(Item &));
其中,pf指向一个将Item引用作为参数的函数(不是成员函数),Item是列表中数据项的类型。visit()函数将该函数用于列表中的每个数据项。
相关文章推荐
- 读书笔记MoreEffectiveC++(9)
- C语言中的预编译指令
- 深入理解C++的动态绑定和静态绑定
- C++编程对缓冲区的理解
- 浅谈C++指针直接调用类成员函数
- 读书笔记MoreEffectiveC++(8)
- C++类的继承总结
- 丢骰子游戏,C语言
- c/c++类型和字节大小整理
- C++ Primer 复习杂记(第六章)
- 使用MinGW搭建windows下C/C++开发环境
- 婚礼上的谎言(C++实现)
- c++ 信号量
- C++ Primer 复习杂记(第五章)
- C语言数据类型
- Java与C++实现相同的MD5加密算法
- 学习文章连载一
- c++实现多态的原理
- c语言二叉堆《学习记录》poj3253
- C++冒泡排序