类和动态内存分配的课后习题(C++ prime plus)
阅读原文时间:2023年07月08日阅读:2

第一题

1. 对于下面的类声明:

class Cow {

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; // display all new data

};

给这个类提供实现,并编写一个使用所有成员函数的小程序。
Cow.h

#ifndef COW_H_
#define COW_H_

class Cow
{
private:
char name[20];
char * hobby;
double weght;
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

Cow.cpp

#include
#include
#include "Cow.h"
using namespace std;

Cow::Cow()
{
strcpy(name,"whp");
hobby=new char [4];
strcpy(hobby,"math");
weght=0.0;
}

Cow::Cow(const char * nm,const char * ho,double wt)
{
strcpy(name,nm);
hobby=new char [strlen(ho)+1];
strcpy(hobby,ho);
weght=wt;
}

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

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

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

void Cow::ShowCow()const
{
cout<<"name: "<<name<<endl;
cout<<"hobby: "<<hobby<<endl;
cout<<"weght: "<<weght<<endl;
cout<<"end"<<endl;
}

UserCow.cpp

#include
#include "Cow.h"
using namespace std;

int main()
{
Cow mycow;
mycow.ShowCow();
Cow mycow1("wer","china",20);
mycow1.ShowCow();
Cow mycow2;
mycow2=mycow;
mycow2.ShowCow();
cout<<"结束"<<endl;
return 0;

}

第二题

通过完成下面的工作来改进String类声明(即将String1.h升级为String2.h)。

a. 对+运算符进行重载,使之可将两个字符串合并成1个。

b. 提供一个Stringlow()成员函数,将字符串中所有的字母字符转换为小写(别忘了cctype系列字符函数)。

c. 提供String()成员函数,将字符串中所有字母字符转换成大写。

d. 提供一个这样的成员函数,它接受一个char参数,返回该字符在字符串中出现的次数
string.h

#ifndef STRING1_H_
#define STRING1_H_
#include
using std::ostream;
using std::istream;

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 &);  
~String();  
int length () const { return len; }  
void string\_change\_low();  
void string\_change\_up();  
int has(char c);  
String & operator=(const String &);  
String & operator=(const char \*);  
String operator+(const String & st)const;  
String operator+(const char \* str1)const;  
char & operator\[\](int i);  
const char & operator\[\](int i) const;

friend bool operator<(const String &st, const String &st2);  
friend bool operator>(const String &st1, const String &st2);  
friend bool operator==(const String &st, const String &st2);  
friend String operator+(const char \* str1,const String & st);  
friend ostream & operator<<(ostream & os, const String & st);  
friend istream & operator>>(istream & is, String & st);

static int HowMany();  

};
#endif

string.cpp

#include
#include "string1.h"
using std::cin;
using std::cout;
#include

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;
}

void String::string_change_low()
{
for(int i=0;ilen+1;i++)
{
this->str[i]=towlower(this->str[i]);
}
}

void String::string_change_up()
{
for(int i=0;ilen+1;i++)
{
this->str[i]=toupper(this->str[i]);
}
}
int String::has(char c)
{
int count=0;
for(int i=0;ilen+1;i++)
{
if(this->str[i]==c)
{
count++;
}
}
return count;
}

String String::operator+(const String & st)const
{
int new_len=0;
new_len=len+st.len;
char * temp=new char [new_len+1];
strcpy(temp,str);
strcpy(temp+len,st.str);
temp[new_len]='\0';
return String(temp);

}

String String::operator+(const char * str1)const
{
int new_len=0;
new_len=len+strlen(str);
char *temp=new char [new_len+1];
strcpy(temp,str);
strcpy(temp,str1);
return String(temp);

}

String operator+(const char * str1,const String & st)
{
return String(str1)+st;
}
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;
}

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;
}

UserString.cpp

#include
using namespace std;
#include "string1.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.string_change_up(); cout << "The string\n" << s2 << "\ncontains " << s2.has('A') << " '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.string_change_low();
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;
}

第三题

新编写程序清单10.7和程序清单10.8描述的Stock类,使之使用动态内存分配的内存,而不是string类对象来存储股票名称。另外,使用重载的operator<<()定义代替show()成员函数。再使用程序清单10.9测试新的定义程序。

Stock20.h

#ifndef STOCK20_H_
#define STOCK20_H_
#include
#include
#include
#include
using namespace std;
class Stock
{
private:
char * company;
int shares;
double share_val;
double total_val;
void set_tot() { total_val = shares * share_val; }
public:
Stock();
Stock(const char * strs, 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 ostream & operator<<(ostream & os,const Stock & st);
const Stock & topval(const Stock & s) const;
};

#endif

Stcok20.cpp

#include
#include "stock20.h"

Stock::Stock()
{
company=new char [strlen("whp")+1];
strcpy(company,"whp");
shares = 0;
share_val = 0.0;
total_val = 0.0;
}

Stock::Stock(const char * strs, long n, double pr)
{
int len=strlen(strs);
company=new char [len+1];
strcpy(company,strs);

if (n < 0)  
{  
    std::cout << "Number of shares can’t be negative; "  
                << company << " shares set to 0.\\n";  
    shares = 0;  
}  
else  
    shares = n;  
share\_val = pr;  
set\_tot();  

}

Stock::~Stock()
{
}

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

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

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

ostream & operator<<(ostream & os,const Stock & st)
{

using std::ios\_base;

ios\_base::fmtflags orig =  
    os.setf(ios\_base::fixed, ios\_base::floatfield);  
std::streamsize prec = os.precision(3);

os << "Company: " <<st.company  
    << " Shares: " <<st.shares << '\\n';  
os << " Share Price: $" <<st.share\_val;

os.precision(2);  
os << " Total Worth: $" <<st.total\_val <<'\\n';  
return os;  

}

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

UserStcok.cpp

#include
#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";  
int st;  
for (st = 0; st < STKS; st++)  
    cout<<stocks\[st\];

const Stock \* top = &stocks\[0\];  
for (st = 1; st < STKS; st++)  
    top = &top->topval(stocks\[st\]);

std::cout << "\\nMost valuable holding:\\n";  
cout<<\*top;  
 return 0;  

}

第四题

Stack.h

#ifndef STOCK_H_
#define STOCK_H_
using namespace std;
#include
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 ostream & operator<<(ostream & os,const Stack & st);  

};

#endif

Stack.cpp

#include
#include "Stack.h"

Stack::Stack(int n=MAX)
{
pitems=new Item[n];//分配空间
for(int i=0;i<n;i++)//初始化数组
{
pitems[i]=0;
}
top=0;
size=n;
}

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

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;
top=st.top;
size=st.size;
pitems=new Item[st.size];
for(int i=0;i<st.size;i++)
{
pitems[i]=st.pitems[i];
}
return *this;

}

ostream & operator<<(ostream & os,const Stack & st)
{
for(int i=0;i<st.top;i++)
{
os<<st.pitems[i]<<endl;
}
return os;
}

UserStack.cpp

#include
#include
#include "Stack.h"
int main()
{
using namespace std;
Stack st;
char ch;
unsigned long 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 number to add: "; cin >> po;
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);
cout << "PO #" << po << " popped\n";
}
break;
}
cout << "Please enter A to add a purchase order,\n"
<< "P to process a PO, or Q to quit.\n";
}
Stack st2;
st2=st;
cout<<"st2"<<st2<<endl;
cout << "Bye\n";
return 0;
}

第五题

Heather银行进行的研究表明,ATM客户不希望排队时间不超过1分钟。使用程序清单12.10中的模拟,找出要使平均等候时间为1分钟,每小时到达的客户数应为多少(试验时间不短于100小时)?

Queue.h

#ifndef STACK_H_
#define STACK_H_

class Customer
{
private:
long arrive;
int processtime;
public:
Customer(){arrive=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

customer.cpp

#include
#include "Queue.h"

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;
rear->next=add;
rear=add;
return true;

}

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

bank.cpp

#include
#include "Queue.h"
#include
#include

const int MIN_PER_HR=60;

bool newcustomer(double x);

int main()
{
using std::cin;
using std::cout;
using std::endl;
using std::ios_base;
std::srand(std::time(0));

cout<<"Case Study:Band of Heather Automatic Teller\\n";  
cout<<"Enter maximum size of queue:";  
int qs;  
cin>>qs;  
Queue line(qs);

cout<<"Enter the number of simulation hours:";  
int hours;  
cin>>hours;  
long cyclelimit=MIN\_PER\_HR\*hours;

cout<<"Enter the average number of customer 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;  
long wait\_time=0;  
long line\_wait=0;  
double avetime=0;

while(perhour++&&avetime<=1)  
{  
    while(!line.isempty())  
    {  
        line.dequeue(temp);  
    }

for(int cycle=0;cycle<cyclelimit;cycle++)  
{  
    if(newcustomer(min\_per\_cust))  
    {  
        if(line.isfull())  
            turnaways++;  
        else  
        {  
            customers++;  
            temp.set(cycle);  
            line.enqueue(temp);  
        }  
    }  
    if(wait\_time<0&&line.isempty())  
    {  
        line.dequeue(temp);  
        wait\_time=temp.ptime();  
        line\_wait+=cycle-temp.when();  
        served++;  
    }  
    if(wait\_time>0)  
        wait\_time--;  
    sum\_line+=line.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: "  
         << (double) line\_wait / served << " minutes\\n";  
}  
else  
    cout << "No customers!\\n";  
avetime=(double)line\_wait/served;  
}  
cout<<"When there comes"<<perhour<<"people per hour,the average wait time will be about 1 inutes.\\n"<<endl;  
cout<<"Done";  
return 0;  

}

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