c++ Primer Plus(第六版)第十二章习题,写代码之路

时间:2023-02-24 08:31:13

c++ Primer Plus(习题12.1)

//12.1头文件
#pragma once
#ifndef COW_H
#define COW_H
#include<iostream>
#include<cstring>
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 // !COW_H


#include"cow.h"


Cow::Cow()
{
name[0] = '\0';
hobby = new char[1];
hobby[0] = '\0';//为了与后面析构函数的delete配套,nullptr为空指针新关键字
weight = 0.0;
}

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

Cow::Cow(const Cow&c)//复制构造函数
{
std::strcpy(name, c.name);
hobby = new char[std::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;//删除指针再指向的内存
hobby = new char[std::strlen(c.hobby) + 1];
std::strcpy(name, c.name);
std::strcpy(hobby, c.hobby);
weight = c.weight;
return *this;//this为对象指针,值向调用对象
}

void Cow::ShowCow()const
{
std::cout << "Name: " << name << std::endl
<< "Hobby: " << hobby << std::endl
<< "Weight: " << weight << std::endl;
}

c++ Primer Plus(习题12.2)

//自己的string 类,顺便做题目
#pragma once
#ifndef MYSTRING_H
#define MYSTRING_H
#include<iostream>
using std::ostream;
using std::istream;
class String
{
private:
char *str;
int len;
static int num_strings; //静态类成员
static const int CINLIMN = 80;//字符串的最大值
public:
//构造函数和其它方法
String(const char*s);
String();
~String();
String(const String &s);//复制构造函数
int length()const { return len; }
//运算符重载
String operator+(const String&s)const;//合并
String operator+(const char*);//合并
String& operator=(const String&s);
String&operator=(const char*);//字符串赋值
char &operator[](int i);//重载[]运算符,给字符串某位置赋值
const char&operator[](int i)const;
String &stringlow();//把字符串变成小写
String &stringup();
int has(char a);//记录字符出现次数
//友元函数
friendString operator+(char *st, const String&s);//重载一个字符串与string合并
friend bool operator<(const String&st, const String&st2);
friend bool operator>(const String&st, const String&st2);
friend bool operator==(const String&st, const String&st2);
friend ostream&operator<<(ostream&os, const String &st);
friend istream&operator >> (istream&is,String&st);
//静态成员函数,智能使用静态类成员
static int HowMaxny();

};
#endif // !MYSTRING_H

#include<cctype>#include<cstring>#include"mystring.h"using std::cout;using std::cin;//初始化静态类成员int String::num_strings = 0;//静态类方法int String::HowMaxny(){return num_strings;}//成员方法String::String(const char*s){len = 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 &s){num_strings++;len = s.len;str = new char[len + 1];std::strcpy(str, s.str);}String::~String(){--num_strings;delete[] str;}//重载的运算符方法//将string对象复制给string对象String& String::operator=(const String&s){if (this == &s)return *this;delete[]str;len = s.len;str = new char[len + 1];std::strcpy(str, s.str);return *this;}//将字符串复制给对象String& String::operator=(const char*z){delete[]str;len = strlen(z);str = new char[len + 1];std::strcpy(str, z);return *this;}//重载加号使字符串合并,与string合并String String::operator+(const String&s)const{String temp;temp.len = len + s.len;delete[]temp.str;temp.str = new char[temp.len + 1];std::strcpy(temp.str, str);std::strcat(temp.str, s.str);return temp;}//与字符串合并,字符串在后面String String::operator+(const char*s){String temp;temp.len = len + strlen(s);delete[]temp.str;temp.str = new char[temp.len+1];std::strcpy(temp.str, str);std::strcat(temp.str, s);return temp;}//字符串在前面与string对象合并String operator+(char *st, const String&s){String temp;temp.len = strlen(st) + s.len;delete[]temp.str;temp.str = new char[temp.len + 1];std::strcpy(temp.str, st);//问题在这里,strcpy写成strcatstd::strcat(temp.str, s.str);return temp;}//改写字符串中的某个字符char &String::operator[](int i){return str[i];}//只是读string中的某个字符const char &String::operator[](int i)const{return str[i];}bool operator<(const String&st, const String&st2){return (std::strcmp(st.str, st2.str)<0);}bool operator>(const String&st, const String&st2){return st2 < st;//直接换简单粗暴}bool operator==(const String&st, const String&st2){return (std::strcmp(st.str, st2.str)==0);}//把字符串全部变成小写String &String::stringlow()//考虑要不要改变原字符串{int i = 0;while (i<len){str[i] = std::tolower(str[i]);//糊涂了,这里把str的指针地址增加了,导致程序崩溃i++;}return *this;}//把字符串全部变成大写,会改变原字符串 String &String::stringup(){int i = 0;while (i<len){str[i] = std::toupper(str[i]);//糊涂了,这里把str的指针地址增加了,导致程序崩溃i++;//按以前的把str指针增加的量减回去}return *this;}int String::has(char a)//记录字符出现次数{int counts = 0;int i = 0;while (i<len){if (str[i]== a)counts++;i++;}return counts;}ostream&operator<<(ostream&os, const String &st){os << st.str;return os;}istream&operator >> (istream&is, String&st){char temp[String::CINLIMN];is.get(temp, String::CINLIMN);if (is)st = temp;while (is&&is.get() != '\n')continue;return is;}
//书上提供的测试#include<iostream>using namespace std;#include"mystring.h"int main()                                 {String s1(" and i am a C++ student.");String s2 = "Please enter you 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.has('A')<< " 'A' characters in it.\n";s1 = "red";String rgb[3] = { String(s1),String("green"),String("blue") };cout << "Enter the name of 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;elsecout << "Try again!\n";}cout << "Bye!\n";return 0;}

c++ Primer Plus(习题12.3)

//stock.h  
#ifndef STOCK_H_
#define STOCK_H_
#include<iostream>
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 *co, long n = 0, double pr = 0.0);
Stock(const Stock &);
~Stock();
void buy(long num, double price);
void sell(long num, double price);
void update(double price);
const Stock & topval(const Stock & s)const;
Stock & operator=(const Stock & s);
friend ostream & operator<<(ostream & os, const Stock & s);
};
#endif
#include<iostream>  #include "stock.h"  Stock::Stock() {company = new char[8];strcpy(company, "no name");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(company, co);if (n < 0){cout << "Number of shares can't be negative; "<< company << " shares set to 0.\n";shares = 0;}elseshares = n;share_val = pr;set_tot();}Stock::Stock(const Stock & s) {int len = strlen(s.company);company = new char[len + 1];strcpy(company, s.company);shares = s.shares;set_tot();}Stock::~Stock() {delete[] company;}void Stock::buy(long num, double price) {if (num < 0){cout << "Number of shares purchased cannot be negative. " << "Transaction is aborted.\n";}else{shares += num;share_val = price;set_tot();}}void Stock::sell(long num, double price) {if (num < 0){cout << "Number of shares sold cannot be negative. " << "Transaction is aborted.\n";}else if (num > shares) {cout << "You cannot 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();}const Stock & Stock::topval(const Stock & s)const {if (s.total_val > total_val)return s;elsereturn *this;}Stock & Stock::operator=(const Stock & s) {int len = strlen(s.company);company = new char[len + 1];strcpy(company, s.company);shares = s.shares;set_tot();return *this;}ostream & operator<<(ostream & os, const Stock & s) {ios_base::fmtflags orig = cout.setf(ios_base::fixed, ios_base::floatfield);streamsize prec = cout.precision(3);cout << "Company: " << s.company << " Shares: " << s.shares << '\n';cout << " Share Price: $" << s.share_val;cout.precision(2);cout << " Total Worth: $" << s.total_val << '\n';cout.setf(orig, ios_base::floatfield);cout.precision(prec);return os;}
//又是熟悉的方法,注意new和delete的配合就行,书上大部分的源码#include <iostream>  #include "stock.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)};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]);}cout << "\nMost valuable holding:\n";cout << *top;cin.get();return 0;}




c++ Primer Plus(习题12.4)

//stock.h  
#ifndef STOCK_H_
#define STOCK_H_
#include<iostream>
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 *co, long n = 0, double pr = 0.0);
Stock(const Stock &);
~Stock();
void buy(long num, double price);
void sell(long num, double price);
void update(double price);
const Stock & topval(const Stock & s)const;
Stock & operator=(const Stock & s);
friend ostream & operator<<(ostream & os, const Stock & s);
};
#endif
#include<iostream>  #include "stock.h"  Stock::Stock() {company = new char[8];strcpy(company, "no name");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(company, co);if (n < 0){cout << "Number of shares can't be negative; "<< company << " shares set to 0.\n";shares = 0;}elseshares = n;share_val = pr;set_tot();}Stock::Stock(const Stock & s) {int len = strlen(s.company);company = new char[len + 1];strcpy(company, s.company);shares = s.shares;set_tot();}Stock::~Stock() {delete[] company;}void Stock::buy(long num, double price) {if (num < 0){cout << "Number of shares purchased cannot be negative. " << "Transaction is aborted.\n";}else{shares += num;share_val = price;set_tot();}}void Stock::sell(long num, double price) {if (num < 0){cout << "Number of shares sold cannot be negative. " << "Transaction is aborted.\n";}else if (num > shares) {cout << "You cannot 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();}const Stock & Stock::topval(const Stock & s)const {if (s.total_val > total_val)return s;elsereturn *this;}Stock & Stock::operator=(const Stock & s) {int len = strlen(s.company);company = new char[len + 1];strcpy(company, s.company);shares = s.shares;set_tot();return *this;}ostream & operator<<(ostream & os, const Stock & s) {ios_base::fmtflags orig = cout.setf(ios_base::fixed, ios_base::floatfield);streamsize prec = cout.precision(3);cout << "Company: " << s.company << " Shares: " << s.shares << '\n';cout << " Share Price: $" << s.share_val;cout.precision(2);cout << " Total Worth: $" << s.total_val << '\n';cout.setf(orig, ios_base::floatfield);cout.precision(prec);return os;}

//书上的一个测试程序,觉得赋值运算符没体现出来,复制构造函数也没用。
#include<iostream>
#include<cctype>
#include"stack.h"
int main()
{
using namespace std;
char ch;
Stack st;
unsigned long po;
cout << "Please enter A to add a customer name and payment,\n"
<< "D to delete a customer,or Q to exit.\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 is full!\n";
else
st.push(po);
break;
case'd':
case'D':
if (st.isempty())
cout << "stack already empty.\n";
else
{
st.pop(po);
cout << "PO # " << po << " been delete!\n";
}
break;
}
cout << "Please enter A to add a customer name and payment,\n"
<< "D to delete a customer,or Q to exit.\n";
}
cout << "Bye!\n";
return 0;
}




c++ Primer Plus(习题12.5)

//c++版,书上的源码
#pragma once
#pragma execution_character_set("utf-8")
//本文件为utf-8编码格式
#ifndef QUEUE_H_
#define QUEUE_H_
using namespace std;
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

#include"myqueue.h"
#include<cstdlib>
Queue::Queue(int qs) :qsize(qs) {
front = rear = nullptr;
items = 0;
}
Queue::~Queue() {
Node *temp;
while (front != nullptr) {
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 (items == qsize)
return false;
Node *add = new Node;
add->item = item;
add->next = nullptr;
items++;
if (front == nullptr)
front = add;
else
rear->next = add;
rear = add;
return true;
}
bool Queue::dequeue(Item &item) {
if (items == 0)
return false;
item = front->item;
items--;
Node *temp = front;
front = front->next;
delete temp;
if (items == 0)
rear = nullptr;
return true;
}
void Customer::set(long when) {
processtime = std::rand() % 3 + 1;
arrive = when;
}
//书上的源码,题目的意思是自己玩他设计的这个程序//来模拟银行挣钱的秘诀,看懂了程序改一下简单,但本人没怎么改,增加了一个队列而已//秘诀就是平均每小时来50个人,等候时间大于200;#include <iostream>  #include <cstdlib>  #include <ctime>  #include "myqueue.h"  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);Queue line2(qs);cout << "Enter the number of simulation hours: ";//测试的时间int hours;cin >> hours;long cyclelimit = MIN_PER_HR*hours;cout << "Enter the average number of cunstomers 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;//取款机空闲的等待时间long wait_time2 = 0;long line_wait = 0;//队列的总等待时间for (long 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())line1.enqueue(temp);elseline2.enqueue(temp);}}if (wait_time1 <= 0 && !line1.isempty()){line1.dequeue(temp);wait_time1 = temp.ptime();line_wait += cycle - temp.when();served++;}if (wait_time2 <= 0 && !line2.isempty()){line2.dequeue(temp);wait_time2 = temp.ptime();line_wait += cycle - temp.when();served++;}if (wait_time1 > 0)wait_time1--;if (wait_time2 > 0)wait_time2--;sum_line += (line1.queuecount() + line2.queuecount()) / 2;}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";}elsecout << "No customers!\n";cout << "Done!\n";return 0;}bool newcustomer(double x) {return (rand()*x / RAND_MAX < 1);}


过年前清完,这个寒假才有意义············