C++PrimerPlus中文第六版第12章编程练习答案
1、
// cow.h #ifndef COW_H_ #define COW_H_ #include<iostream> class Cow { private: char name[20]; char* hobby; double weight; public: Cow(); Cow(const char* nm, const char* hb, double wt); Cow(const Cow& c); ~Cow(); Cow& operator=(const Cow& c); void ShowCow() const; }; #endif
// cow.cpp #include<iostream> #include"cow.h" Cow::Cow() { name[0] = '\0'; hobby = nullptr; weight = 0.0; } Cow::Cow(const char* nm, const char* hb, double wt) { strcpy_s(name, 20, nm); int len = strlen(hb); hobby = new char[len+1]; strcpy_s(hobby, len + 1, hb); weight = wt; } Cow::Cow(const Cow& c) { strcpy_s(name, c.name); int len = strlen(c.hobby); hobby = new char[len + 1]; strcpy_s(hobby, len + 1, c.hobby); weight = c.weight; } Cow::~Cow() { delete[] hobby; } Cow& Cow::operator=(const Cow& c) { if (this == &c) return *this; strcpy_s(name,20, c.name); int len = strlen(c.hobby); hobby = new char[len + 1]; strcpy_s(hobby, len + 1, c.hobby); weight = c.weight; return *this; } void Cow::ShowCow() const { using std::cout; using std::endl; if (name[0] == '\0') cout << "Name is empty,\n"; else cout << "Name: " << name << endl; if (hobby == nullptr) cout << "Hobby is NULL.\n"; else cout << "Hobby: " << hobby << endl; cout << "Weight: " << weight << endl; }
#include<iostream> #include"cow.h" int main() { Cow c1; c1.ShowCow(); Cow c2("cow2", "grass", 100.0); c2.ShowCow(); Cow c3 = c2; c3.ShowCow(); Cow c4; c4 = c3; c4.ShowCow(); return 0; }
2、
// string.h #ifndef STRING_H_ #define STRING_H_ #include<iostream> class String { private: char* str; int len; static int num_strings; static const int CINLIM = 80; public: String(); String(const char* s); String(const String& s); ~String(); friend bool operator<(const String& s1, const String& s2); friend bool operator>(const String& s1, const String& s2) { return s2 < s1; }; friend bool operator==(const String& s1, const String& s2); // 习题新增功能 friend String operator+(const String& s1, const String& s2); // 拼接两个字符串 void Stringlow(); // 转换成小写 void Stringup(); // 转换成大写 int chartimes(const char& ch); // 统计字符ch在字符串中出现的次数 friend std::ostream& operator<<(std::ostream& os, const String& s); friend std::istream& operator>>(std::istream& is, String& s); String& operator=(const String& s); // 赋值运算符必须显示定义 String& operator=(const char* s); // 字符串赋值给类对象 char& operator[](int i); const char& operator[](int i) const; int length() { return len; } static int HowMany(); //静态成员函数 }; #endif
// string.cpp #pragma warning(disable : 4996) #include<iostream> #include<string> #include"String.h" int String::num_strings = 0; // 初始化静态数据成员 // 静态成员函数只能访问静态数据成员,对类的私有成员不能访问 int String::HowMany() { return num_strings; } String::String() // 默认构造函数 { len = 0; str = nullptr; num_strings++; } String::String(const char* s) //带一个参数的构造函数 { len = strlen(s); str = new char[len + 1]; strcpy_s(str, len + 1, s); num_strings++; } String::String(const String& s) // 复制构造函数 { len = strlen(s.str); str = new char[len + 1]; strcpy_s(str, len + 1, s.str); num_strings++; } String::~String() { delete[] str; num_strings--; } // 关系运算符 bool operator<(const String& s1, const String& s2) { return strcmp(s1.str, s2.str) < 0; } bool operator==(const String& s1, const String& s2) { return strcmp(s1.str, s2.str) == 0; } // []运算符 char& String::operator[](int i) { return str[i]; } const char& String::operator[](int i) const { return str[i]; } // 赋值运算符 String& String::operator=(const String& s) { if (this == &s) return *this; delete[] str; len = strlen(s.str); str = new char[len + 1]; strcpy_s(str, len + 1, s.str); return *this; } // 重载赋值运算符 String& String::operator=(const char* s) { delete[] str; len = strlen(s); str = new char[len + 1]; strcpy_s(str, len + 1, s); return *this; } // 输入输出运算符重载 std::ostream& operator<<(std::ostream& os, const String& s) { os << s.str; return os; } std::istream& operator>>(std::istream& is, String& s) { char temp[String::CINLIM]; is.get(temp, String::CINLIM); if (is) s = temp; while (is && is.get() != '\n') continue; return is; } // 习题新增加的功能 String operator+(const String& s1, const String& s2) { int len = s1.len + s2.len; char* str = new char[len + 1]; strcpy_s(str, len+1, s1.str); strcat_s(str, len+1, s2.str); String temp(str); delete[] str; return temp; } void String::Stringlow() { strlwr(this->str); } void String::Stringup() { strupr(this->str); } int String::chartimes(const char& ch) { int times = 0; for (int i = 0; i < len; i++) if (ch == str[i]) times++; return times; }
#pragma warning(disable : 4996) #include<iostream> #include"string.h" using namespace std; 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" << s2 << "\ncontains " << s2.chartimes('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.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"; } } return 0; }
3、
// stock.h #ifndef STOCK_H_ #define STOCK_H_ #include<iostream> 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* co, long n, 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& s); const Stock& topval(const Stock& s) const; }; #endif
// stock.cpp #include<iostream> #include"stock.h" Stock::Stock() { company = nullptr; shares = 0; share_val = 0.0; total_val = 0.0; } Stock::Stock(const char* co, long n, double pr) { int len = strlen(co); company = new char[len + 1]; strcpy_s(company, len + 1, co); shares = std::max(n, long(0)); // shares can't be negative. share_val = std::max(pr, double(0.0)); // share_val can't be negative, either. set_tot(); } Stock::~Stock() { delete[] company; } void Stock::buy(long num, double price) { if (num < 0) std::cout << "Number of shares purchased can't be negaive. Transaction is aborted.\n"; else if (price < 0) std::cout << "Shares value 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 << "Numbers 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 if (price < 0) cout << "Value of shares sold can't be negative. Transaction is aborted.\n"; else { shares -= num; share_val = price; set_tot(); } } void Stock::update(double price) { if (price < 0) std::cout << "Shares price can't be negative. Failure of Updating Operation.\n"; else { share_val = price; set_tot(); } } std::ostream& operator<<(std::ostream& os, const Stock& s) { using std::ios_base; ios_base::fmtflags orig = os.setf(ios_base::fixed, ios_base::floatfield); std::streamsize prec = os.precision(3); os << "Company: " << s.company << ", Shares: " << s.shares << std::endl; os << "Share Price: $" << s.share_val; os.precision(2); os << ", Total Worth: $" << s.total_val << std::endl; os.setf(orig, ios_base::floatfield); os.precision(prec); return os; } const Stock& Stock::topval(const Stock& s) const { if (s.total_val > this->total_val) return s; else return *this; }
main函数省略了懒得测试
4、
// stack.h #ifndef STACK_H_ #define STACK_H_ #include<iostream> typedef unsigned long Item; class Stack { private: static const int 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
// stack.cpp #include<iostream> #include"stack.h" Stack::Stack(int n) { if (n == 0) pitems = nullptr; else pitems = new Item[n]; size = n; top = 0; } Stack::Stack(const Stack& st) { int len; if (st.pitems == nullptr) { len = 0; pitems = nullptr; } else { len = _msize(st.pitems) / sizeof(Item); // _msize()函数获取动态申请内存的数组空间大小 pitems = new Item[len]; } for (int i = 0; i < len; i++) pitems[i] = st.pitems[i]; size = len; top = st.top; } Stack::~Stack() { delete[] pitems; } bool Stack::isempty() const { return top == 0; } bool Stack::isfull() const { return top == size; } bool Stack::push(const Item& item) { if (top < size) { pitems[top] = item; top++; 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; int len; if (st.pitems == nullptr) { len = 0; pitems = nullptr; } else { len = _msize(st.pitems) / sizeof(Item); // _msize()函数获取动态申请内存的数组空间大小 pitems = new Item[len]; } for (int i = 0; i < len; i++) pitems[i] = st.pitems[i]; size = len; top = st.top; return *this; } std::ostream& operator<<(std::ostream& os, const Stack& st) { using std::endl; for (int i = 0; i < st.top; i++) os << st.pitems[i] << ", "; os << endl; os << "size: " << st.size << endl; os << "top: " << st.top << endl; return os; }
#include<iostream> #include"stack.h" int main() { using namespace std; Stack st; char ch; unsigned long po; cout << "Please enter A to add a purchase order, P to process a purchase order, and Q to quit.\n"; while (cin >> ch and toupper(ch) != 'Q') { while (cin.get() != '\n') continue; if (!isalpha(ch)) { cout << '\a'; continue; } switch (ch) { case 'A': case 'a': cout << "Enter a purchased order to add: "; cin >> po; if (st.isfull()) { cout << "stack is already full.\n"; } else st.push(po); break; case 'p': case 'P': if (st.isempty()) { cout << "stack is already empty.\n"; } else { st.pop(po); cout << "purchaes order #" << po << " poped.\n"; } break; } cout << "Please enter A to add a purchase order, P to process a purchase order, and Q to quit.\n"; } Stack st1 = st; cout << st1 << endl; Stack st2; st2 = st; cout << st2 << endl; }
5、略
6、
// queue.h #ifndef QUEUE_H_ #define QUEUE_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; Node* next; }; static const int Q_SIZE = 10; Node* front; Node* rear; int items; const int qsize; public: Queue(int qs = Q_SIZE); ~Queue(); Queue(const Queue& q); Queue& operator=(const Queue& q); bool isempty() const; bool isfull() const; int queuecount(); // 队列元素个数 bool enqueue(const Item& item); bool dequeue(Item& item); }; #endif
// queue.cpp #include<cstdlib> #include"queue.h" void Customer::set(long when) { arrive = when; processtime = rand() % 3 + 1; // 客户交易时间随机为1,2,3分钟 } Queue::Queue(int qs) : qsize(qs) // 成员初始化列表,在类对象创建之前,也就是给数据成员分配内存之前进行数据成员的初始化 { front = rear = nullptr; items = 0; } Queue::~Queue() { Node* temp; while (front != NULL) { temp = front; front = front->next; delete temp; } } Queue::Queue(const Queue& q) : qsize(q.qsize) // 重定义复制构造函数 { items = q.items; if (items == 0) { front = rear = nullptr; } else { Node* p = q.front; Node* temp = new Node; temp->item = p->item; front = temp; while (p->next != NULL and p != rear) { p = p->next; Node* temp1 = new Node; temp1->item = p->item; temp->next = temp1; temp = temp->next; } temp->next = nullptr; rear = temp; } } Queue& Queue::operator=(const Queue& q) // 重载赋值运算符 { if (this == &q) return *this; items = q.items; if (items == 0) { front = rear = nullptr; } else { Node* p = q.front; Node* temp = new Node; temp->item = p->item; front = temp; while (p->next != NULL and p != rear) { p = p->next; Node* temp1 = new Node; temp1->item = p->item; temp->next = temp1; temp = temp->next; } temp->next = nullptr; rear = temp; } return *this; } bool Queue::isempty() const { return items == 0; } bool Queue::isfull() const { return items == qsize; } int Queue::queuecount() { return items; } bool Queue::enqueue(const Item& item) { if (isfull()) return false; Node* add = new Node; add->item = item; add->next = nullptr; if (front == nullptr) front = add; else rear->next = add; rear = add; items++; return true; } bool Queue::dequeue(Item& item) { if (isempty()) return false; item = front->item; Node* temp = front; if (front == rear) front = rear = nullptr; else front = front->next; delete temp; items--; return true; }
// corresponding to bank.cpp in book #include<iostream> #include<cstdlib> #include<ctime> #include"queue.h" const int MINU_PER_HR = 60; bool newcustomer(double x); // 判断是否有新的客户到来 int main() { using std::cout; using std::cin; using std::endl; using std::ios_base; srand(time(0)); // 设置新的随机种子 cout << "Bank of Automatic Teller Machine\n"; cout << "Enter max size of queue: "; int qs; cin >> qs; Queue line1(qs); // line queue holds up to qs people, initialize to an empty queue Queue line2(qs); cout << "Enter the number of simulation hours: "; int hours; cin >> hours; // simulation will run 1 cycle per minute long cyclelim = hours * MINU_PER_HR; cout << "Enter the average number of customers per hour: "; double perhour; cin >> perhour; double minu_per_cust = MINU_PER_HR / perhour; // average time between arrivals long turnaways = 0; // turned away by full queue long customers = 0; // joined the queue long served = 0; // served during the simulation long sum_line = 0; // cumulative line length int wait_time1 = 0; // time=0 until autoteller is free int wait_time2 = 0; // time=0 until autoteller is free long line_wait = 0; // cumulative time in line // run simulation Item temp; for (int cycle = 0; cycle < cyclelim; cycle++) { // 每分钟开始判断是否有新的顾客到来 if (newcustomer(minu_per_cust)) // 如果有新的顾客到来 { if (line1.isfull() and line2.isfull()) { turnaways++; cout << turnaways << "th customer turn away.\n"; } else { customers++; temp.set(cycle); if (line1.queuecount() < line2.queuecount()) line1.enqueue(temp); else line2.enqueue(temp); //cout << customers << "th customer enqueue\n"; } } if (wait_time1 <= 0 and !line1.isempty()) { line1.dequeue(temp); wait_time1 = temp.ptime(); line_wait += cycle - temp.when(); served++; } if (wait_time2 <= 0 and !line2.isempty()) { line2.dequeue(temp); wait_time2 = temp.ptime(); line_wait += cycle - temp.when(); served++; } if (wait_time1 > 0) { wait_time1--; //cout << served << "th customer serving----------\n"; } if (wait_time2 > 0) { wait_time2--; //cout << served << "th customer serving----------\n"; } sum_line += line1.queuecount(); sum_line += line2.queuecount(); } // report results if (customers > 0) { cout << "Customer accepted: " << customers << endl; cout << "Customer served: " << served << endl; cout << "Turned aways: " << turnaways << endl; cout << "Average queue size: "; cout.precision(2); cout.setf(ios_base::fixed, ios_base::floatfield); cout << double(sum_line) / 2 / cyclelim << endl; cout << "Average wait time: " << double(line_wait) / served << "minutes\n"; } else { cout << "No customers.\n"; } return 0; } bool newcustomer(double x) { // 能模拟每x分钟会有一个顾客到来 return x * rand() / RAND_MAX < 1; }

浙公网安备 33010602011771号