C++ Primer 第五版 第一章 开始 习题详解
有的过于简单,省略不写
1.2 返回值-1,观察系统如何处理
1 #include <iostream>
2 using namespace std;
3
4 int main()
5 {
6 return -1;
7 }
`linux系统和windows系统都是返回-1的反码,作为无符号数处理。
linux: echo $? 来查看系统状态
windows,编译器直接显示:
1.8
1 #include <iostream>
2 using namespace std;
3
4 int main()
5 {
6 cout << "/*" << endl;
7 cout << "*/" << endl;
8 cout << /* "*/" */;
9 cout << /* "*/" /* "/*" */ << endl;
10
11 return 0;
12 }
1、2、4正确,3错误,需要在最后再加一个‘ ” ’可见系统是从左到右进行匹配。
1.9 用while循环将50到一百的整数相加
1 #include <iostream>
2 using namespace std;
3
4 int main()
5 {
6 int val = 50, sum = 0;
7 while ( val <= 100 )
8 sum += val, ++val;
9
10 cout << sum << endl;
11
12 return 0;
13 }
14
运行结果为3825;
1.10 按递减顺序打印出10到0之间的整数
1 #include <iostream>
2 using namespace std;
3
4 int main()
5 {
6 int i = 10;
7 while ( i >= 0 )
8 cout << i << ' ', --i;
9 cout << endl;
10
11 return 0;
12 }
1.11 打印出两个整数所指定的范围内所有的整数:
2 #include <iostream>
3 using namespace std;
4
5 int main()
6 {
7 int a, b;
8
9 cin >> a >> b ;
10 //先分类讨论a, b的大小
11 while ( a== b)
12 {cout << " Not having anything " << endl; break;}
13 while ( a < b)
14 while( ++a < b )
15 cout << a << endl;
16 while ( a > b )
17 while( b++ < a )
18 cout << b << endl;
19 return 0;
20 }
1.14 for循环和while循环的比较
在for循环中,循环控制变量的初始化和修改都放在语句头部分,形式较简洁,且特别适用于循环次数已知的情况。在while循环中,循环控制变量的初始化一般放在while语句之前,循环控制变量的修改一般放在循环体中,形式上不如for语句简洁,但它比较适用于循环次数不易预知的情况(用某一条件控制循环)。两种形式各有优点,但它们在功能上是等价的,可以相互转换。
1.16
#include <iostream>
using namespace std;
void main()
{
int num,sum = 0;
while (cin>>num)
{
sum = sum+num;
cout<<sum<<endl;
}//可以一直不停的输入,按control + D 结束输入
1.17-1.18 都是正常输出,区别就是前者输入一次就结束,后者需要再输入;
1 #include <iostream>
2 using namespace std;
3
4 int main()
5 {
6 int cur;
7 int times = 0;
8 if ( cin >> cur ){
9 ++times;
10 int val;
11 while ( cin >> val ){
12 if ( cur == val){
13 ++times;
14 }
15 else{
16 cout << cur << " occurs " << times << " times" << endl;
17 cur = val;
18 times = 1;
19 }
20 }
21 cout << cur << " occurs" << times << " times" << endl;
22 }
23 return 0;
24 }
~
1.20-1.25
自己写的类,程序如下:(我是有一定基础才看的书,用到了很多后面才会学到的知识),只能统计连续相同的记录,离散的不行,后面会改进。
1 #ifndef SALES_ITEM_H
2 #define SALES_ITEM_H
3 #include <iostream>
4 #include <string>
5
6 using namespace std;
1 #ifndef SALES_ITEM_H
2 #define SALES_ITEM_H
3 #include <iostream>
4 #include <string>
5
6 using namespace std;
7
8 class Sales_item{
9
10 string ISBN;
11 int salevolume;
12 float avprice;
13 //友元,可以访问内部私有的成员
14 friend istream& operator>>(istream&, Sales_item& x);
15 friend ostream& operator<<(ostream& o, Sales_item& x);
16 public:
17 Sales_item(string i = string(), int s = int(), int a = int()):ISBN(i), salevolume(s), avprice(a){
18 //cout << i << " " << s << " " << a << endl;
19 }
20 Sales_item& operator+=(Sales_item& x)
21 {
22 this->avprice = (this->salevolume*this->avprice + x.salevolume*x.avprice)/(this->salevolume+x.salevolume);
23 this->salevolume += x.salevolume;
24 }
25 Sales_item& operator=(Sales_item& x)
26 {
27 this->ISBN = x.ISBN;
28 this->salevolume = x.salevolume;
29 this->avprice = x.avprice;
30 }
31 const string& getISBN()
32 {
33 return ISBN;
34 }
35
36 };
37 //运算符函数
38 istream& operator>>(istream& i, Sales_item& x)
39 {
40 cin >> x.ISBN >> x.salevolume >> x.avprice ;
41 }
42 ostream& operator<<(ostream& o, Sales_item& x)
43 {
44
45 cout << x.ISBN << " " << x.salevolume << " " << x.avprice ;
46 }
47 #endif
1 /*书店保存所有销售记录的档案
2 * 每条记录保存了某本书的一次销售信息
3 * 有时,书店老板需要查询档案,计算每本书的销售量、销售额及平均售价
4 */
5
6 #include <iostream>
7 #include "Sale_item.h"
8
9 using namespace std;
10
11
12 int main()
13 {
14 Sales_item total;//保存下一条交易记录的变量
15 //读入第一条交易记录,并确保有数据可以处理
16 if ( cin >> total ){
17 //存储当前输入记录
18 Sales_item cur;
19 //读入并处理剩下交易记录
20 while ( cin >> cur ){
21 //如果我们仍然在处理相同的书
22 if ( total.getISBN() == cur.getISBN() ){
23 total += cur;//更新记录
24 }
25 else{
26 cout << "-------------" << endl;
27 //输出记录
28 cout << total << endl;
29 //更新书籍记录
30 total = cur;
31 }
32 }
33 //打印最后一本书的结果
34 cout << total << endl;
35 }
36 else{
37 //没有输入!警告读者
38 cerr << "No data?!" << endl;
39 return -2;
40 }
41 return 0;
7月24日,用链表数据结构改写了,由于没有用上动态内存分配,导致除了第一条和最后一条记录以外的都会被覆盖掉,后面还会改进:
1 #include <iostream>
2 #include <string>
3
4 using namespace std;
5
6
7 class Book{
8 public:
9 string name;
10 unsigned salevolume;
11 double price;
12 Book *next;
13 friend istream& operator>>(istream&, Book& x);
14 friend ostream& operator<<(ostream& o, Book& x);
15 public:
16 Book(string i = string(), int s = int(), int a = int(), Book *next = nullptr):name(i), salevolume(s), price(a)
17 {
18 //cout << i << " " << s << " " << a << endl;
19 }
20 Book& operator+=(Book& x)
21 {
22 this->price = (this->salevolume*(this)->price + x.salevolume*x.price)/(this->salevolume+x.salevolume);
23 this->salevolume += x.salevolume;
24 }
25 Book& operator=(Book& x)
26 {
27 this->name = x.name;
28 this->salevolume = x.salevolume;
29 this->price = x.price;
30 }
31 };
32
33 //运算符函数
34 istream& operator>>(istream& i, Book& x)
35 {
36 cin >> x.name >> x.salevolume >> x.price ;
37 }
38 ostream& operator<<(ostream& o, Book& x)
39 {
40
41 cout << x.name << " " << x.salevolume << " " << x.price ;
42 }
43 //定义记录库类
44 class library{
45 public:
46 Book* begin= nullptr;//头结点
47 Book* tail= nullptr;//尾结点
48 unsigned record_volume = 0;//库里面记录的条数
49 void record_add(Book& newbook)
50 {
51 if (begin == nullptr)
52 {
53 begin = &newbook;
54 tail = &newbook;
55 newbook.next = nullptr;
56 }
57 else
58 {
59 tail->next = &newbook;
60 newbook.next = nullptr;
61 tail = &newbook;
62 }
63 }
64 Book* record_search( string& n)
65 {
66 //定义搜索指针
67 Book* temp = begin;
68 while (temp)
69 {
70 if (temp->name == n)
71 {
72 cout << n << endl;
73 cout << temp->name << endl;
74 cout << &n << endl;
75 cout << &(temp->name) << endl;
76 cout << "重复" << endl;
77 break;
78 }
79 temp = temp->next;
80 }
81
82 return temp;
83
84 }
85 void record_print(){
86 //定义打印指针
87 Book* temp1 = begin;
88 while (temp1)
89 {
90 cout << temp1->name << " " << temp1->salevolume << " " << temp1->price << endl;
91 temp1 = temp1->next;
92 }
93 cout << record_volume << endl;
94 }
95 };
96
97 int main()
98 {
99 Book first; //定义第一条记录
100 library book_record;//定义一个书籍销售记录库
101 if ( cin >> first ){
102 book_record.record_add(first);//记录库中添加第一条记录
103 ++book_record.record_volume;
104 //存储当前新输入记录
105 Book cur;
106 //读入并处理剩下交易记录
107 while ( cin >> cur )
108 {
109 ++book_record.record_volume;
110 Book *temp = book_record.record_search(cur.name);
111 if (!temp)//如果记录库里没有该书籍的记录,则添加进库,否则加入到记录库中该条记录;
112 {
113 book_record.record_add(cur);
114 cout << "------" << endl;
115
116 }
117 else
118 {
119 *temp += cur;
120 cout << "........." << endl;
121 }
122
123 }
124
125 book_record.record_print();
126 }
127 else{
128 //没有输入!警告读者
129 cerr << "No data?!" << endl;
130 return -2;
131 }
132
133
134 return 0;
135 }
7月25日,用上了动态内存:
1 #include <iostream>
2 #include <string>
3
4 using namespace std;
5
6
7 class Book{
8 public:
9 string name;
10 unsigned salevolume;
11 double price;
12 Book *next;
13 friend istream& operator>>(istream&, Book& x);
14 friend ostream& operator<<(ostream& o, Book& x);
15 public:
16 Book(string i = string(), int s = int(), int a = int(), Book *next = nullptr):name(i), salevolume(s), price(a)
17 {
18 //cout << i << " " << s << " " << a << endl;
19 }
20 Book& operator+=(Book& x)
21 {
22 this->price = (this->salevolume*(this)->price + x.salevolume*x.price)/(this->salevolume+x.salevolume);
23 this->salevolume += x.salevolume;
24 }
25 Book& operator=(Book& x)
26 {
27 this->name = x.name;
28 this->salevolume = x.salevolume;
29 this->price = x.price;
30 }
31 };
32
33 //运算符函数
34 istream& operator>>(istream& i, Book* x)
35 {
36 cin >> x->name >> x->salevolume >> x->price ;
37 }
38 ostream& operator<<(ostream& o, Book& x)
39 {
40
41 cout << x.name << " " << x.salevolume << " " << x.price ;
42 }
43 //定义记录库类
44 class library{
45 public:
46 Book* begin= nullptr;//头结点
47 Book* tail= nullptr;//尾结点
48 unsigned record_volume = 0;//库里面记录的条数
49 void record_add(Book* newbook)
50 {
51 if (begin == nullptr)
52 {
53 begin = newbook;
54 tail = newbook;
55 newbook->next = nullptr;
56 }
57 else
58 {
59 tail->next = newbook;
60 newbook->next = nullptr;
61 tail = newbook;
62 }
63 }
64 Book* record_search( string& n)
65 {
66 //定义搜索指针
67 Book* temp = begin;
68 while (temp)
69 {
70 if (temp->name == n)
71 {
72 /*
73 cout << n << endl;
74 cout << temp->name << endl;
75 cout << &n << endl;
76 cout << &(temp->name) << endl;
77 cout << "重复" << endl;
78 */
79 break;
80 }
81 temp = temp->next;
82 }
83
84 return temp;
85
86 }
87 void record_print(){
88 //定义打印指针
89 Book* temp1 = begin;
90 while (temp1)
91 {
92 cout << temp1->name << " " << temp1->salevolume << " " << temp1->price << endl;
93 temp1 = temp1->next;
94 }
95 cout << record_volume << endl;
96 }
97 Book* record_input(){
98 Book * ptr = new Book;
99 cin >> ptr->name >> ptr->salevolume >> ptr->price;
100
101 return ptr;
102
103 }
104 };
105
106 int main()
107 {
108 Book* first = new Book; //定义第一条记录
109 library book_record;//定义一个书籍销售记录库
110
111 cout <<"Please enter the first record: " << endl;
112
113 if ( cin >> first ){
114 book_record.record_add(first);//记录库中添加第一条记录
115 ++book_record.record_volume;
116 int flag = 1;
117
118 cout << "Please enter the next record(Y/N): " << endl;
119
120 while ( flag )
121 {
122 static char ch;
123
124 cin >> ch;
125 while ( ch == 'Y' || ch == 'N' ) {
126 if ( ch == 'Y' )
127 {
128 Book *input = book_record.record_input();
129 ++book_record.record_volume;
130 Book *search = book_record.record_search(input->name);
131 if (!search)//如果记录库里没有该书籍的记录,则添加进库,否则加入到记录库中该条记录;
132 {
133 book_record.record_add(input);
134
135 }
136 else
137 {
138 *search += *input;
139 }
140 }
141 else
142 {
143 flag = 0;
144 break;
145 }
146
147 cout << "Do you want to input again(Y/N): " << endl;
148 cin >> ch;
149 }
150
151 if ( ch != 'Y' && ch != 'N' )
152 {
153 cout << "Wrong!! please input again(Y/N): " << endl;
154 }
155 }
156
157
158 book_record.record_print();
159 }
160 else{
161 //没有输入!警告读者
162 cerr << "No data?!" << endl;
163 return -2;
164 }
165
166
167 return 0;
168 }
附本书作者提供的头文件Sales_item.h代码:
```cpp
#ifndef SALESITEM_H
// we're here only if SALESITEM_H has not yet been defined
#define SALESITEM_H
// Definition of Sales_item class and related functions goes here
#include <iostream>
#include <string>
class Sales_item {
// these declarations are explained section 7.2.1, p. 270
// and in chapter 14, pages 557, 558, 561
friend std::istream& operator>>(std::istream&, Sales_item&);
friend std::ostream& operator<<(std::ostream&, const Sales_item&);
friend bool operator<(const Sales_item&, const Sales_item&);
friend bool
operator==(const Sales_item&, const Sales_item&);
public:
// constructors are explained in section 7.1.4, pages 262 - 265
// default constructor needed to initialize members of built-in type
Sales_item(): units_sold(0), revenue(0.0) { }
Sales_item(const std::string &book):
bookNo(book), units_sold(0), revenue(0.0) { }
Sales_item(std::istream &is) { is >> *this; }
public:
// operations on Sales_item objects
// member binary operator: left-hand operand bound to implicit this pointer
Sales_item& operator+=(const Sales_item&);
// operations on Sales_item objects
std::string isbn() const { return bookNo; }
double avg_price() const;
// private members as before
private:
std::string bookNo; // implicitly initialized to the empty string
unsigned units_sold;
double revenue;
};
// used in chapter 10
inline
bool compareIsbn(const Sales_item &lhs, const Sales_item &rhs)
{ return lhs.isbn() == rhs.isbn(); }
// nonmember binary operator: must declare a parameter for each operand
Sales_item operator+(const Sales_item&, const Sales_item&);
inline bool
operator==(const Sales_item &lhs, const Sales_item &rhs)
{
// must be made a friend of Sales_item
return lhs.units_sold == rhs.units_sold &&
lhs.revenue == rhs.revenue &&
lhs.isbn() == rhs.isbn();
}
inline bool
operator!=(const Sales_item &lhs, const Sales_item &rhs)
{
return !(lhs == rhs); // != defined in terms of operator==
}
// assumes that both objects refer to the same ISBN
Sales_item& Sales_item::operator+=(const Sales_item& rhs)
{
units_sold += rhs.units_sold;
revenue += rhs.revenue;
return *this;
}
// assumes that both objects refer to the same ISBN
Sales_item
operator+(const Sales_item& lhs, const Sales_item& rhs)
{
Sales_item ret(lhs); // copy (|lhs|) into a local object that we'll return
ret += rhs; // add in the contents of (|rhs|)
return ret; // return (|ret|) by value
}
std::istream&
operator>>(std::istream& in, Sales_item& s)
{
double price;
in >> s.bookNo >> s.units_sold >> price;
// check that the inputs succeeded
if (in)
s.revenue = s.units_sold * price;
else
s = Sales_item(); // input failed: reset object to default state
return in;
}
std::ostream&
operator<<(std::ostream& out, const Sales_item& s)
{
out << s.isbn() << " " << s.units_sold << " "
<< s.revenue << " " << s.avg_price();
return out;
}
double Sales_item::avg_price() const
{
if (units_sold)
return revenue/units_sold;
else
return 0;
}
#endif