您的位置:首页 > 编程语言 > C语言/C++

c++.primer.plus第五版第十章编程练习答案

2015-07-23 19:08 603 查看
第一题、复习题5中的类:

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()函数将该函数用于列表中的每个数据项。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: