C++ Primer Plus 第六版(中文版)第十二章(完美修订版)编程练习答案(类和动态内存分配)

//本章程序需分多文件运行,请读者注意;

//本博主所写的代码仅为阅读者提供参考;

//若有不足之处请提出,博主会尽所能修改;

//附上课后编程练习题目;

//若是对您有用的话请点赞或分享提供给它人;


//--------------------------------------------------------------------
//12.10 - 1(main).cpp

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

int main()
{
    
    
    using std::cout;
    using std::endl;

    Cow temp1;
    Cow temp2("Clover", "Computer", 30);
    Cow temp3(temp2);

    cout << "Here are some cows:" << endl;
    cout << "The first:" << endl;
    temp1.ShowCow();
    cout << "The second:" << endl;
    temp2.ShowCow();
    cout << "The third:" << endl;
    temp3.ShowCow();
    temp1 = temp3;
    cout << "After assignment for temp1:" << endl;
    temp1.ShowCow();

    return 0;
}

//12.10 - 1(cow).h

#ifndef COW_H_
#define COW_H_

class Cow
{
    
    
private:
    char name[20];
    char *hobby;
    double weight;

public:
    Cow();                                          //默认构造函数;
    Cow(const char *nm, const char *ho, double wt); //用户定义构造函数;
    Cow(const Cow &c);                              //复制构造函数;
    ~Cow();                                         //析构函数;
    Cow &operator=(const Cow &c);                   //运算符重载;
    void ShowCow() const;                           //显示类私有成员的全部内容;
};

#endif

//12.10 - 1(cow).cpp

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

Cow::Cow()
{
    
    
    std::strcpy(name, "\0");
    hobby = new char[1]; //对应析构函数释放内存;
    hobby[0] = '\0';
    weight = 0.0;
}

Cow::Cow(const char *nm, const char *ho, double wt)
{
    
    
    std::strncpy(name, nm, 20);
    name[19] = '\0';
    hobby = new char[strlen(ho) + 1];
    std::strcpy(hobby, ho);
    weight = wt;
}

Cow::Cow(const Cow &c)
{
    
    
    std::strcpy(name, c.name);
    hobby = new char[strlen(c.hobby) + 1];
    std::strcpy(hobby, c.hobby);
    weight = c.weight;
}

Cow::~Cow()
{
    
    
    delete[] hobby;
}

Cow &Cow::operator=(const Cow &c)
{
    
    
    if (this == &c)
    {
    
    
        return *this;
    }
    delete[] hobby;
    std::strcpy(name, c.name);
    hobby = new char[strlen(c.hobby) + 1];
    std::strcpy(hobby, c.hobby);
    weight = c.weight;
    return *this;
}

void Cow::ShowCow() const
{
    
    
    std::cout << "Cow name: " << name << std::endl;
    std::cout << "Cow hobby: " << hobby << std::endl;
    std::cout << "Cow weight: " << weight << "\n\n";
    return;
}

//--------------------------------------------------------------------

//--------------------------------------------------------------------
//12.10 - 2(main).cpp

#include <iostream>
using namespace std;
#include "string2.h"

int main()
{
    
    
    String s1(" and I am a C++ student.");
    String s2 = "Please enter your name: ";
    String s3;

    cout << s2;
    cin >> s3;
    s2 = "My name is " + s3;
    cout << s2 << ".\n";
    s2 = s2 + s1;
    s2.stringup();
    cout << "The string \n";
    cout << s2 << "\ncontains " << s2.has('A');
    cout << " 'A' characters in it.\n";
    s1 = "red";

    String rgb[3] = {
    
    String(s1), String("green"), String("blue")};
    cout << "Enter the name of a primary color for mixing light: ";
    String ans;
    bool success = false;
    while (cin >> ans)
    {
    
    
        ans.stringlow();
        for (int i = 0; i < 3; i++)
        {
    
    
            if (ans == rgb[i])
            {
    
    
                cout << "That's right!\n";
                success = true;
                break;
            }
        }
        if (success)
        {
    
    
            break;
        }
        else
        {
    
    
            cout << "Try again!\n";
        }
    }
    cout << "Bye\n";

    return 0;
}

//12.10 - 2(string2).h

#ifndef STRING2_H_
#define STRING2_H_
#include <iostream>
using std::istream;
using std::ostream;

class String
{
    
    
private:
    char *str;                    //字符串首字符指针;
    int len;                      //记录字符串长度;
    static int num_strings;       //记录构造的字符串数目;
    static const int CINLIM = 80; //限制输入字符个数;

public:
    String(const char *s);    //用户定义构造函数;
    String();                 //默认构造函数;
    String(const String &st); //复制构造函数;
    ~String();                //析构函数;
    int length() const {
    
     return len; }
    String &operator=(const String &st);
    String &operator=(const char *s);
    String operator+(const char *s); //重载'+'使得String类可以和const char *进行相加;
    char &operator[](int i);
    const char &operator[](int i) const;
    friend bool operator<(const String &st1, const String &st2);
    friend bool operator>(const String &st1, const String &st2);
    friend bool operator==(const String &st1, const String &st2);
    friend ostream &operator<<(ostream &os, const String &st);
    friend istream &operator>>(istream &is, String &st);
    friend String operator+(const char *s, const String &st);      //重载'+'使得const char *可以和String类进行相加;
    friend String operator+(const String &st1, const String &st2); //重载'+'使得String类可以相加;
    void stringlow();                                              //使得字符串字母转换成小写;
    void stringup();                                               //使得字符串字母转换成大写;
    unsigned has(const char s) const;                              //计算单个字符在字符串中出现的次数;
    static int HowMany();
};

#endif

//12.10 - 2(string2).cpp

#include <cctype>
#include <cstring>
#include "string2.h"
using std::cin;
using std::cout;

int String::num_strings = 0;

int String::HowMany()
{
    
    
    return num_strings;
}

String::String(const char *s)
{
    
    
    len = std::strlen(s);
    str = new char[len + 1];
    std::strcpy(str, s);
    num_strings++;
}

String::String()
{
    
    
    len = 4;
    str = new char[1];
    str[0] = '\0';
    num_strings++;
}

String::String(const String &st)
{
    
    
    num_strings++;
    len = st.len;
    str = new char[len + 1];
    std::strcpy(str, st.str);
}

String::~String()
{
    
    
    --num_strings;
    delete[] str;
}

String &String::operator=(const String &st)
{
    
    
    if (this == &st)
    {
    
    
        return *this;
    }
    delete[] str;
    len = st.len;
    str = new char[len + 1];
    std::strcpy(str, st.str);
    return *this;
}

String &String::operator=(const char *s)
{
    
    
    delete[] str;
    len = std::strlen(s);
    str = new char[len + 1];
    std::strcpy(str, s);
    return *this;
}

String String::operator+(const char *s)
{
    
    
    int length = strlen(s) + len;
    char *temp = new char[length + 1]; //分配内存;
    strcpy(temp, str);                 //进行字符串赋值;
    strcat(temp, s);                   //进行连接;
    return String(temp);               //构造一个新的String对象并作为返回值;
}

char &String::operator[](int i)
{
    
    
    return str[i];
}

const char &String::operator[](int i) const
{
    
    
    return str[i];
}

bool operator<(const String &st1, const String &st2)
{
    
    
    return (std::strcmp(st1.str, st2.str) < 0);
}

bool operator>(const String &st1, const String &st2)
{
    
    
    return st2 < st1;
}

bool operator==(const String &st1, const String &st2)
{
    
    
    return (std::strcmp(st1.str, st2.str) == 0);
}

ostream &operator<<(ostream &os, const String &st)
{
    
    
    os << st.str;
    return os;
}

istream &operator>>(istream &is, String &st)
{
    
    
    char temp[String::CINLIM];
    is.get(temp, String::CINLIM);
    if (is)
    {
    
    
        st = temp;
    }
    while (is && is.get() != '\n')
        continue;
    return is;
}

String operator+(const char *s, const String &st)
{
    
    
    int length = strlen(s) + st.len;
    char *temp = new char[length + 1];
    strcpy(temp, s);
    strcat(temp, st.str);
    return String(temp);
}

String operator+(const String &st1, const String &st2)
{
    
    
    int length = st1.len + st2.len;
    char *temp = new char[length + 1];
    strcpy(temp, st1.str);
    strcat(temp, st2.str);
    return String(temp);
}

void String::stringlow()
{
    
    
    for (int i = 0; i < len; i++)
    {
    
    
        str[i] = tolower(str[i]);
    }
    return;
}

void String::stringup()
{
    
    
    for (int i = 0; i < len; i++)
    {
    
    
        str[i] = toupper(str[i]);
    }
    return;
}

unsigned String::has(const char s) const
{
    
    
    unsigned count = 0;

    for (int i = 0; i < len; i++)
    {
    
    
        if (s == str[i])
        {
    
    
            ++count;
        }
    }
    return count;
}

//--------------------------------------------------------------------

//--------------------------------------------------------------------
//12.10 - 3(main).cpp

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

const int STKS = 4;

int main()
{
    
    
    Stock stocks[STKS] = 
    {
    
    
        Stock("NanoSmart", 12, 20.0),
        Stock("Boffo Objects", 200, 2.0),
        Stock("Monolithic Obelisks", 130, 3.25),
        Stock("Fleep Enterprises", 60, 6.5)
    };

    std::cout << "Stock holdings:\n";
    for (int st = 0; st < STKS; st++)
    {
    
    
        std::cout << stocks[st] << std::endl;
    }
    const Stock *top = &stocks[0];
    for (int st = 1; st < STKS; st++)
    {
    
    
        top = &top->topval(stocks[st]);
    }
    std::cout << "\nMost valuable holding:\n";
    std::cout << *top;

    return 0;
}

//12.10 - 3(stock20).h

#ifndef STOCK20_H_
#define STOCK20_H_
#include <iostream>

class Stock
{
    
    
private:
    char *company; //为了使用new分配的内存从而改变类型为char *指针;
    int shares;
    double share_val;
    double total_val;
    void set_tot() {
    
     total_val = shares * share_val; }

public:
    Stock();
    Stock(const char *s, long n = 0, double pr = 0.0);
    ~Stock();
    void buy(long num, double price);
    void sell(long num, double price);
    void update(double price);
    friend std::ostream &operator<<(std::ostream &os, const Stock &st);
    const Stock &topval(const Stock &s) const;
};

#endif

//12.10 - 3(stock20).cpp

#include <iostream>
#include "stock20.h"
using namespace std;
#include <cstring>

Stock::Stock()
{
    
    
    company = new char[1]; //与析构函数相对应;
    company[0] = '\0';
    shares = 0;
    share_val = 0.0;
    total_val = 0.0;
}

Stock::Stock(const char *s, long n, double pr)
{
    
    
    company = new char[strlen(s) + 1]; //使用new动态分配内存;
    std::strcpy(company, s);
    if (n < 0)
    {
    
    
        std::cout << "Number of shares can't be negative; ";
        std::cout << company << " shares set to 0.\n";
        shares = 0;
    }
    else
    {
    
    
        shares = n;
    }
    share_val = pr;
    set_tot();
}

Stock::~Stock()
{
    
    
    delete[] company; //释放构造函数中new分配的内存;
}

void Stock::buy(long num, double price)
{
    
    
    if (num < 0)
    {
    
    
        std::cout << "Number of shares purchased can't be negative. ";
        std::cout << "Transaction is aborted.\n";
    }
    else
    {
    
    
        shares += num;
        share_val = price;
        set_tot();
    }
    return;
}

void Stock::sell(long num, double price)
{
    
    
    using std::cout;
    if (num < 0)
    {
    
    
        cout << "Number of shares sold can't be negative. ";
        cout << "Transaction is aborted.\n";
    }
    else if (num > shares)
    {
    
    
        cout << "You can't sell more than you have! ";
        cout << "Transaction is aborted.\n";
    }
    else
    {
    
    
        shares -= num;
        share_val = price;
        set_tot();
    }
    return;
}

void Stock::update(double price)
{
    
    
    share_val = price;
    set_tot();
    return;
}

std::ostream &operator<<(std::ostream &os, const Stock &st)
{
    
    
    os << "Company: " << st.company << std::endl;
    os << "Shares: " << st.shares << std::endl;
    os << "Share Price: " << st.share_val << std::endl;
    os << "Total Worth: " << st.total_val << std::endl;
    return os;
}

const Stock &Stock::topval(const Stock &s) const
{
    
    
    if (s.total_val > total_val)
    {
    
    
        return s;
    }
    else
    {
    
    
        return *this;
    }
}

//--------------------------------------------------------------------

//--------------------------------------------------------------------
//12.10 - 4(main).cpp

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

int main()
{
    
    
    using namespace std;
    Stack st;
    Item temp = 1000UL;
    st.push(temp);
    temp = 2000UL;
    st.push(temp);
    temp = 3000UL;
    st.push(temp);
    Stack st1(st);
    Stack st2;
    st2 = st1;
    cout << "Here are some stack contents:" << endl;
    cout << "Stack st:" << endl;
    cout << st;
    cout << "Stack st1:" << endl;
    cout << st1;
    cout << "Stack st2:" << endl;
    cout << st2;
    cout << "Bye\n";

    return 0;
}

//12.10 - 4(stack).h

#ifndef STACK_H_
#define STACK_H_
#include <iostream>

typedef unsigned long Item;

class Stack
{
    
    
private:
    enum {
    
    MAX = 10};
    Item *pitems;
    int size;
    int top;

public:
    Stack(int n = MAX);
    Stack(const Stack &st);
    ~Stack();
    bool isempty() const;
    bool isfull() const;
    bool push(const Item &item);
    bool pop(Item &item);
    Stack &operator=(const Stack &st);
    friend std::ostream &operator<<(std::ostream &os, const Stack &st);
    //重载'<<'运算符查看复制构造函数和赋值运算符是否编写正确;
};

#endif

//12.10 - 4(stack).cpp

#include "stack.h"

Stack::Stack(int n)
{
    
    
    top = 0;
    if (n > MAX) //长度大于MAX时的情况;
    {
    
    
        std::cout << "The length of stack can't exceed 10.\n";
        std::cout << "So initialize the length to 10.\n";
        size = MAX;
    }
    else if (n < 0) //长度小于0的情况;
    {
    
    
        std::cout << "The length of stack can't less than 0.\n";
        std::cout << "So initialize the length to 10.\n";
        size = MAX;
    }
    else
    {
    
    
        size = n;
    }
    pitems = new Item[size];
}

Stack::Stack(const Stack &st)
{
    
    
    size = st.size;
    top = st.top;
    pitems = new Item[size]; //动态数组;
    for (int i = 0; i < top; i++)
    {
    
    
        pitems[i] = st.pitems[i];
    }
}

Stack::~Stack()
{
    
    
    delete[] pitems; //释放动态数组内存;
}

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

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

bool Stack::push(const Item &item)
{
    
    
    if (top < MAX)
    {
    
    
        pitems[top++] = item;
        return true;
    }
    else
    {
    
    
        return false;
    }
}

bool Stack::pop(Item &item)
{
    
    
    if (top > 0)
    {
    
    
        item = pitems[--top];
        return true;
    }
    else
    {
    
    
        return false;
    }
}

Stack &Stack::operator=(const Stack &st)
{
    
    
    if (this == &st)
    {
    
    
        return *this;
    }
    delete[] pitems;
    size = st.size;
    top = st.top;
    pitems = new Item[size];
    for (int i = 0; i < top; i++)
    {
    
    
        pitems[i] = st.pitems[i];
    }
    return *this;
}

std::ostream &operator<<(std::ostream &os, const Stack &st)
{
    
    
    for (int i = st.top - 1; i >= 0; i--) //栈顶到栈底打印元素;
    {
    
    
        os << st.pitems[i] << std::endl;
    }
    return os;
}

//--------------------------------------------------------------------

//--------------------------------------------------------------------

12.10 - 5题直接用书上的程序进行模拟,不用修改任何代码,在队列长度为10和试验时间在100小时的情况下要使平均等候时间为1分钟的话,每小时到达的顾客数应该在18人左右。

//--------------------------------------------------------------------

//--------------------------------------------------------------------
//12.10 - 6(main).cpp

#include <iostream>
#include <cstdlib>
#include <ctime>
#include "queue.h"
using namespace std;
const int MIN_PER_HR = 60;

bool newcustomer(double x);

int main()
{
    
    
    srand(time(0));

    cout << "Case Study: Bank of Heather Automatic Teller\n";
    cout << "Enter maximum size of queue: ";
    int qs;
    cin >> qs;
    Queue line1(qs); //构造第一台ATM机;
    Queue line2(qs); //构造第二台ATM机;

    cout << "Enter the number of simulation hours: ";
    int hours;
    cin >> hours;
    long cyclelimit = MIN_PER_HR * hours;

    cout << "Enter the average number of customers per hour: ";
    double perhour;
    cin >> perhour;
    double min_per_cust;
    min_per_cust = MIN_PER_HR / perhour;

    Item temp;
    long turnaways = 0;
    long customers = 0;
    long served = 0;
    long sum_line = 0;
    int wait_time1 = 0; //第一台ATM机的等待时间;
    int wait_time2 = 0; //第二台ATM机的等待时间;
    long line_wait = 0;

    for (int cycle = 0; cycle < cyclelimit; cycle++)
    {
    
    
        if (newcustomer(min_per_cust))
        {
    
    
            if (line1.isfull() && line2.isfull())
                turnaways++;
            else
            {
    
    
                customers++;
                temp.set(cycle);
                if (line1.queuecount() <= line2.queuecount()) //第一台ATM机人数小于第二台;
                {
    
    
                    line1.enqueue(temp); //顾客排在第一队;
                }
                else
                {
    
    
                    line2.enqueue(temp); //否则排在第二队;
                }
            }
        }
        if (wait_time1 <= 0 && !line1.isempty())
        {
    
    
            line1.dequeue(temp);
            wait_time1 = temp.ptime();
            line_wait += cycle - temp.when();
            served++;
        }
        if (wait_time1 > 0)
        {
    
    
            wait_time1--;
        }
        sum_line += line1.queuecount();
        if (wait_time2 <= 0 && !line2.isempty())
        {
    
    
            line2.dequeue(temp);
            wait_time2 = temp.ptime();
            line_wait += cycle - temp.when();
            served++;
        }
        if (wait_time2 > 0)
        {
    
    
            wait_time2--;
        }
        sum_line += line2.queuecount();
    }

    if (customers > 0)
    {
    
    
        cout << "customers accepted: " << customers << endl;
        cout << "  customers served: " << served << endl;
        cout << "         turnaways: " << turnaways << endl;
        cout << "average queue size: ";
        cout.precision(2);
        cout.setf(ios_base::fixed, ios_base::floatfield);
        cout << (double)sum_line / cyclelimit << endl;
        cout << " average wait time: ";
        cout << (double)line_wait / served << " minutes\n";
    }
    else
    {
    
    
        cout << "No customers!\n";
    }
    cout << "Done!\n";

    return 0;
}

bool newcustomer(double x)
{
    
    
    return (std::rand() * x / RAND_MAX < 1);
}

//12.10 - 6(queue).h

#ifndef QUEUE_H_
#define QUEUE_H_

class Customer
{
    
    
private:
    long arrive;
    int processtime;

public:
    Customer() : arrive(0L), processtime(0) {
    
    }
    void set(long when);
    long when() const {
    
     return arrive; }
    int ptime() const {
    
     return processtime; }
};

typedef Customer Item;

class Queue
{
    
    
private:
    struct Node{
    
     Item item; struct Node *next; };
    enum {
    
     Q_SIZE = 10 };
    Node *front;
    Node *rear;
    int items;
    const int qsize;
    Queue(const Queue &q) : qsize(0) {
    
    }
    Queue &operator=(const Queue &q) {
    
     return *this; }

public:
    Queue(int qs = Q_SIZE);
    ~Queue();
    bool isempty() const;
    bool isfull() const;
    int queuecount() const;
    bool enqueue(const Item &item);
    bool dequeue(Item &item);
};

#endif

//12.10 - 6(queue).cpp

#include "queue.h"
#include <cstdlib>

Queue::Queue(int qs) : qsize(qs)
{
    
    
    front = rear = NULL;
    items = 0;
}

Queue::~Queue()
{
    
    
    Node *temp;
    while (front != NULL)
    {
    
    
        temp = front;
        front = front->next;
        delete temp;
    }
}

bool Queue::isempty() const
{
    
    
    return items == 0;
}

bool Queue::isfull() const
{
    
    
    return items == qsize;
}

int Queue::queuecount() const
{
    
    
    return items;
}

bool Queue::enqueue(const Item &item)
{
    
    
    if (isfull())
    {
    
    
        return false;
    }
    Node *add = new Node;
    add->item = item;
    add->next = NULL;
    items++;
    if (front == NULL)
    {
    
    
        front = add;
    }
    else
    {
    
    
        rear->next = add;
    }
    rear = add;
    return true;
}

bool Queue::dequeue(Item &item)
{
    
    
    if (front == NULL)
    {
    
    
        return false;
    }
    item = front->item;
    items--;
    Node *temp = front;
    front = front->next;
    delete temp;
    if (items == 0)
    {
    
    
        rear = NULL;
    }
    return true;
}

void Customer::set(long when)
{
    
    
    processtime = std::rand() % 3 + 1;
    arrive = when;
    return;
}

修改主函数程序后,在队列长度为10和试验时间在100小时的情况下要使平均等候时间为1分钟的话,每小时到达的顾客数应该在50人左右。

//--------------------------------------------------------------------

//------------------------------------------2020年11月8日 ----------------------------------------------;

猜你喜欢

转载自blog.csdn.net/m0_46181359/article/details/109561218