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

第一题、复习题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()函数将该函数用于列表中的每个数据项。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值