第一章
1-9
#include <iostream>
int main() {
int s = 50, sum = 0;
while (s <= 100) {
sum += (s++);
}
std::cout << sum << std::endl;
return 0;
}
1-10
#include <iostream>
int main() {
using namespace std;
int s;
s = 10;
do {
cout << s << endl;
} while (s-- > 0);
return 0;
}
1-11
#include <iostream>
int main() {
using namespace std;
int a, b;
cout << "Input two interger:" << endl;
cin >> a >> b;
while (a < b) {
cout << (a++) << endl;
}
return 0;
}
1-12
进行了从[-100,100]数值的求和,sum 最终值为 0
1-16
#include <iostream>
int main() {
using namespace std;
int size, *arr, sum;
cin >> size;
arr = new int[size];
for (int i = 0; i < size; i++) {
cin >> arr[i];
}
sum = 0;
for (int i = 0; i < size; i++) {
sum += arr[i];
}
cout << sum << endl;
}
1-20
#include "include/1/Sales_item.h"
#include <iostream>
int main() {
using namespace std;
Sales_item item[] = {{"book1"}, {"book2"}, {"book3"}};
for (int i = 0; i < 3; i++) {
cout << item[i] << endl;
}
return 0;
}
1-21
#include "include/1/Sales_item.h"
#include <iostream>
int main() {
using namespace std;
Sales_item item1, item2;
cin >> item1 >> item2;
if (item1.isbn() == item2.isbn()) {
cout << item1 + item2 << endl;
return 0;
} else {
cerr << "Date must refer to same ISBN" << endl;
return -1;
}
}
第二章
2-3
#include <iostream>
using namespace std;
int main() {
using namespace std;
unsigned u = 10, u2 = 42;
cout << u2 - u << endl;
cout << u - u2 << endl;
int i = 10, i2 = 42;
cout << i2 - i << endl;
cout << i - i2 << endl;
cout << i - u << endl;
cout << u - i << endl;
}
2-5
(a) char, wchatt, std::string, const wchatt []
(b) int, unsigned int, long, unsigned long, int 八进制, int 十六进制
(c) double, float, long double
(d) int, unsigned int, double, double
2-6
09
不是合法的字面值常量
2-7
(a) std::string
(b) long double
(c) float
(d) long double
2-8
#include <iostream>
int main() {
using namespace std;
cout << "2M\r\n";
cout << "2\tM\r\n";
return 0;
}
第三章
3-2
#include <iostream>
using namespace std;
void do_readline() {
string line;
while (getline(cin, line))
cout << line << endl;
}
void do_readword() {
string word;
while (1) {
cin >> word;
cout << word << endl;
}
}
int main() {
// do_readline();
// do_readword();
return 0;
}
3-3
string 类的输入操作符会将空白字符串作为分隔符,而 getline 不会
3-4
#include <iostream>
using namespace std;
int main() {
using namespace std;
string s1, s2;
cin >> s1 >> s2;
if (s1 == s2) {
cout << "equal" << endl;
} else {
cout << (s1 > s1 ? s1 : s2) << endl;
}
}
3-5
#include <iostream>
int main() {
using namespace std;
string res, s;
while (cin >> s)
res += s;
cout << res << endl;
}
3-6
#include <iostream>
int main() {
using namespace std;
string s = "Helllo cattchen";
for (auto& c : s) {
c = 'X';
}
cout << s << endl;
}
3-7
不能进行替换,需要使用引用,否则为 char 的拷贝
#include <iostream>
int main() {
using namespace std;
string s = "Helllo cattchen";
for (char c : s) {
c = 'X';
}
cout << s << endl;
}
3-9
可以运行不报错
#include <iostream>
int main() {
using namespace std;
string s;
cout << s[0] << endl;
cout << s.capacity() << endl;
}
3-10
#include <cctype>
#include <iostream>
int main() {
using namespace std;
string s;
getline(cin, s);
for (auto& c : s) {
if (ispunct(c)) {
c = ' ';
}
}
cout << s << endl;
}
3-11
不合法,c 的类型为 const char&
3-12
(a) 正确,空的 int vector
(b) 不正确,拷贝构造的参数类型不匹配
(c) 正确,大小的 10 的 vector 且每个元素为"null"
3-13
(a) 0
(b) 10, 都为 0
(c) 10, 都为 42
(d) 1, 为 10
(e) 2, 为 10 42
(f) 10, 都为空 string
(g) 10, 都为"hi"
3-14
#include <iostream>
#include <vector>
int main() {
using namespace std;
vector<int> arr;
string s;
while (cin >> s)
arr.push_back(stoi(s));
cout << "input done!" << endl;
for (const auto& n : arr)
cout << n << endl;
}
3-15
#include <iostream>
#include <vector>
int main() {
using namespace std;
string s;
vector<string> arr;
while (cin >> s)
arr.push_back(s);
return 0;
}
3-17
#include <algorithm>
#include <iostream>
#include <vector>
int main() {
using namespace std;
vector<string> vstr;
string line;
while (cin >> line)
vstr.push_back(line);
for (auto& s : vstr) {
transform(s.begin(), s.end(), s.begin(), ::toupper);
}
for (auto& s : vstr) {
cout << s << endl;
}
return 0;
}
3-18
不合法,需要改用 push_back
3-19
// 1
vector<int> arr (10,42);
// 2
vector<int> arr(10);
for(auto &n:arr)
n = 42;
// 3
vector<int> arr;
for(int i=0;i<10;i++)
arr.push_back(42);
3-20
#include <iostream>
#include <vector>
int main() {
using namespace std;
vector<int> ivec;
string s;
while (cin >> s)
ivec.push_back(stoi(s));
for (int i = 0; i < ivec.size() - 1; i++) {
cout << ivec[i] + ivec[i + 1] << endl;
cout << ivec[ivec.size() - 1 - i] + ivec[ivec.size() - 2 - i] << endl;
}
return 0;
}
3-23
#include <iostream>
#include <vector>
int main() {
using namespace std;
vector<int> ivec = {1, 2, 3, 4, 5, 6, 7, 8, 9, 0};
for (auto it = ivec.begin(); it != ivec.end(); it++)
*it = *it * 2;
for (const auto& n : ivec)
cout << n << endl;
return 0;
}
3-25
#include <iostream>
#include <vector>
int main() {
using namespace std;
vector<unsigned> scores(11, 0);
unsigned grade;
while (cin >> grade)
if (grade <= 100)
*(scores.begin() + (grade / 10)) += 1;
for (const auto& n : scores) {
cout << n << " ";
}
cout << endl;
return 0;
}
3-26
迭代器相加减没有意义
3-27
ac 都为非法,引起编译报错,b 正确,d 编译通过,但是可能在运行时产生错误
3-28
sa 为 10 个 string 对象,都为空字符串
ia 为 10 个 int,都为 0,
sa2 为 10 个 string 对象,都为空字符串
ia2 为 10 个 int,为随机数
3-29
不能 memcpy 直接对 vector 所在内存直接进行复制,达到拷贝的目的
3-30
访问下标为 array_size 的元素时,出现越界,可能引起段错误
3-31
#include <iostream>
int main() {
using namespace std;
constexpr size_t array_size = 10;
int arr[array_size];
for (int i = 0; i < array_size; i++)
arr[i] = i;
return 0;
}
3-34
表达式的值为 p2。指针值进行相加减时是非法的。
3-35
#include <iostream>
int main() {
int arr[] = {1, 2, 3, 4};
for (int i = 0; i < 4; i++)
arr[i] = 0;
return 0;
}
3-36
#include <iostream>
#include <vector>
bool array_compare(int a[], int b[], ssize_t len) {
for (ssize_t i = 0; i < len; i++) {
if (a[i] != b[i])
return false;
}
return true;
}
template <class T> bool vector_compare(std::vector<T> a, std::vector<T> b) {
return a == b;
}
int main() {
using namespace std;
return 0;
}
3-37
hello
每行输出一个字母
3-38
指针的值相加减可能越界,且表示的地址无意义
3-41
#include <iostream>
#include <vector>
int main() {
using namespace std;
int arr[] = {1, 2, 3, 4};
vector<int> ivec(arr, arr + 4);
for (const auto& n : ivec) {
cout << n << endl;
}
return 0;
}
3-42
#include <cstring>
#include <iostream>
#include <vector>
int main() {
using namespace std;
vector<int> ivec{1, 2, 3, 4};
int arr[4];
memcpy(arr, ivec.data(), 4 * sizeof(int));
for (ssize_t i = 0; i < 4; i++)
cout << arr[i] << endl;
return 0;
}
第四章
4-1
105
第六章
6-1
实参为实际传入函数的参数,形参为函数中的参数变量
6-2
(a) 函数返回类型不正确
(b) 没有注明函数返回类型
(c) 花括号不匹配
(d) 缺少花括号
6-3
#include <iostream>
int fact(int n) {
int res = 1;
for (int i = 1; i <= n; i++) {
res *= i;
}
return res;
}
int main() {
using namespace std;
cout << fact(5) << endl;
}
6-4
#include <iostream>
int fact(int n) {
int res = 1;
for (int i = 1; i <= n; i++) {
res *= i;
}
return res;
}
int main() {
using namespace std;
int n;
while (cin >> n)
cout << fact(n) << endl;
return 0;
}
6-5
#include <iostream>
int my_abs(int n) { return n < 0 ? -n : n; }
int main() {
using namespace std;
int n;
while (cin >> n)
cout << my_abs(n) << endl;
return 0;
}
6-7
#include <iostream>
int foo() {
static int s = 0;
if (!s)
return s++;
else
return s;
}
int main() {
using namespace std;
cout << foo() << endl;
cout << foo() << endl;
cout << foo() << endl;
}
6-10
#include <iostream>
void my_swap(int* a, int* b) {
int tmp = *a;
*a = *b;
*b = tmp;
}
int main() {
using namespace std;
int a = 1, b = 2;
cout << a << " " << b << endl;
my_swap(&a, &b);
cout << a << " " << b << endl;
return 0;
}
6-11
#include <iostream>
void reset(int& n) { n = 0; }
int main() {
using namespace std;
int s = 123;
cout << s << endl;
reset(s);
cout << s << endl;
return 0;
}
6-12
#include <iostream>
void my_swap(int& a, int& b) {
int tmp = a;
a = b;
b = tmp;
}
int main() {
using namespace std;
int a = 1, b = 2;
cout << a << " " << b << endl;
my_swap(a, b);
cout << a << " " << b << endl;
return 0;
}
6-13
第一种为传递变量的拷贝,第二种为传递变量的引用
6-16
可以将形参改为const string&s
6-17
不一样,前者可以传递常量引用,后者不能
第七章
7-5
这些函数应该是 const,函数并不修改类内对象,使用 const 成员函数可以同时兼容 const 和非 const Person 对象
7-16
无限制
7-17
使用 class 和 struct 唯一的区别是默认的访问权限,class 默认是 private,struct 默认是 public
7-18
封装通过访问说明符隐藏了类的实现细节,确保用户代码不会无意间破坏封装对象的状态
7-19
对外暴露的成员函数为 public,私有的成员变量为 private
第八章
8-1
istream& read_all(istream& in) {
char c;
while (!in.eof()) {
in >> c;
cout << c << endl;
}
in.clear();
return in;
}
8-3
用于确定流对象状态是否良好
8-4
int main() {
using namespace std;
vector<string> lines;
string line;
ifstream in("in.txt");
while (in >> line)
lines.push_back(line);
return 0;
}
8-5
int main() {
using namespace std;
vector<string> lines;
string line;
ifstream in("in.txt");
while (getline(in, line, ' '))
lines.push_back(line);
return 0;
}
8-6
int main(int argc, const char* argv[]) {
using namespace std;
fstream f(argv[1]);
string s;
while (getline(f, s))
cout << s << endl;
return 0;
}
8-7
int main(int argc, const char* argv[]) {
using namespace std;
ifstream inf(argv[1]);
ofstream outf(argv[2]);
string s;
while (inf >> s) {
transform(s.begin(), s.end(), s.begin(), ::toupper);
outf << s << endl;
}
return 0;
}
8-8
int main(int argc, const char* argv[]) {
using namespace std;
ifstream inf(argv[1]);
ofstream outf(argv[2], ios_base::app);
string s;
while (inf >> s) {
transform(s.begin(), s.end(), s.begin(), ::toupper);
outf << s << endl;
}
return 0;
}
8-9
istringstream& read_all(istringstream& in) {
char c;
while (!in.eof()) {
in >> c;
cout << c << endl;
}
in.clear();
return in;
}
8-10
int main(int argc, const char* argv[]) {
using namespace std;
ifstream fin(argv[1]);
vector<string> lines;
string s;
while (fin >> s)
lines.push_back(s);
for (const auto& line : lines) {
istringstream is(line);
while (is >> s) {
cout << s << endl;
}
}
return 0;
}
第九章
9-1
(a) 使用 list 或者是 forward_list,因为可能需要频繁地中间插入
(b) 使用 deque 或者 list,因为需要两端的插入/删除
(c) 使用 vector,没有中间插入或者两端的插入/删除
9-2
int main(int argc, const char* argv[]) {
using namespace std;
list<deque<int>> s;
}
9-3
end 不提前于 begin
9-4
bool my_find(std::vector<int>::const_iterator begin,
std::vector<int>::const_iterator end, int target) {
while (begin != end) {
if (*(begin++) == target)
return true;
}
return false;
}
9-5
std::vector<int>::const_iterator&
my_find(std::vector<int>::const_iterator& begin,
std::vector<int>::const_iterator& end, int target) {
while (begin != end) {
if (*(begin++) == target)
return begin;
}
return end;
}
9-6
应该修改为 while(iter1 != iter2)
,list 的迭代器不支持随机访问
9-7
应该使用vecotr<int>::size_type
9-8
应该使用string::reference
9-9
begin 可能返回iterator
或者const_iterator
,cbegin 返回const_iterator
9-10
it1
为vector<int>::iterator
,it2
,it3
,it4
为vector<int>::const_iterator
9-11
int main() {
using namespace std;
vector<int> v1;
vector<int> v2(10, 1);
vector<int> v3{1, 2, 3, 4};
vector<int> v4 = {1, 2, 3, 4};
vector<int> v5 = v1;
vector<int> v6(v1);
}
9-12
前者需要保证容器类型和元素类型都相同,后者只需要保证元素类型相同
9-13
int main() {
using namespace std;
list<int> l = {1, 2, 3};
vector<double> v(l.begin(), l.end());
}
9-14
int main() {
using namespace std;
list<const char*> l = {"hello", "cattchen"};
vector<string> v(l.begin(), l.end());
}
9-15
int main() {
using namespace std;
vector<int> v1 = {1, 2, 3}, v2 = {1, 2, 3};
cout << (v1 == v2 ? "equal" : "not equal") << endl;
}
9-17
c1 和 c2 的容器类型、元素类型相同,且元素类型支持比较运算符
9-18
int main() {
using namespace std;
deque<string> d;
string s;
while (cin >> s)
d.push_back(s);
for (const auto& line : d) {
cout << line << endl;
}
}
9-19
int main() {
using namespace std;
// 修改容器类型即可
list<string> d;
string s;
while (cin >> s)
d.push_back(s);
for (const auto& line : d) {
cout << line << endl;
}
}
9-20
int main() {
using namespace std;
list<int> total = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
deque<int> odd, even;
for (const auto& item : total) {
if (item % 2 == 0) {
even.push_back(item);
} else {
odd.push_back(item);
}
}
}
9-21
int main() {
using namespace std;
list<string> lst;
string word;
auto iter = lst.begin();
while (cin >> word)
iter = lst.insert(iter, word);
for (const auto& s : lst) {
cout << s << endl;
}
}
9-22
没有对 iter 进行自增,有死循环。while 循转中进行自增操作
9-24
int main() {
using namespace std;
vector<int> v = {1, 2, 3};
cout << v.at(0) << endl;
cout << v[0] << endl;
cout << v.front() << endl;
cout << *v.begin() << endl;
}
9-25
elem1 和 elem2 相等,不发生删除
elem2 是尾后迭代器,删除 elem1 及之后的元素
9-26
int main() {
using namespace std;
int ia[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 55, 89};
vector<int> v(begin(ia), end(ia));
list<int> l(begin(ia), end(ia));
for (auto it = v.begin(); it != v.end(); it++) {
if (*it % 2 == 0) {
it = v.erase(it);
}
}
for (auto it = l.begin(); it != l.end(); it++) {
if (*it % 2 != 0) {
it = l.erase(it);
}
}
return 0;
}
9-27
int main() {
using namespace std;
forward_list<int> fl{1, 2, 3, 4, 5, 6, 7, 8, 9};
for (auto it = fl.before_begin(); it != fl.end(); it++) {
if (*next(it) % 2 != 0) {
it = fl.erase_after(it);
}
}
for (const auto n : fl) {
cout << n << endl;
}
return 0;
}
9-28
void insert_str(std::forward_list<std::string>& l, std::string& str1,
std::string& str2) {
for (auto it = l.before_begin(); it != l.end(); it++) {
if (*next(it) == str1) {
it = l.insert_after(it, str2);
return;
}
}
}
9-29
先在尾部新增 75 个元素,然后删除后 90 个元素
9-30
元素需要提供默认构造函数
9-31
list 或者是 forward_list 的迭代器不支持运算符+
9-32
合法
9-33
vector 扩容时,可能发生底层数组的改变,导致原来的迭代器不可用
9-34
遇到奇数值后,不停地在奇数值前插入该数值,是个死循环
9-35
capacity 是 vector 底层数组的大小,size 是 vector 实际存放的元素的个数
9-36
不可能
9-37
list 是双向链表,没有对应的底层数组,array 对应的底层数据固定大小
9-38
以 2^n 的趋势扩张
int main() {
vector<int> vi;
for (int i = 0; i < 3000; i++) {
vi.push_back(1);
cout << vi.size() << " " << vi.capacity() << endl;
}
}
9-39
vector 预先扩容为 1024,读入字符串,结束输入后扩容为原来的 1.5 倍
9-41
int main() {
vector<char> vc = {'h', 'e', 'l', 'l', 'o'};
string s(vc.begin(), vc.end());
cout << s << endl;
}
9-42
使用 reserve 提前分配空间
9-43
// 好像还有点问题
void my_replace(string& s, const string& old_val, const string& new_val) {
string::iterator iter1, iter2;
iter1 = s.begin();
while (iter1 != s.end()) {
while (*iter1 == ' ')
iter1++;
iter2 = iter1;
while (iter2 != s.end() && *iter2 != ' ')
iter2++;
string sub(iter1, iter2);
if (sub == old_val) {
iter2 = s.erase(iter1, iter2);
s.insert(iter2 - s.begin(), new_val);
}
iter1 = iter2;
}
}
int main() {
string s = "tho i thru";
my_replace(s, "tho", "though");
cout << s << endl;
}
9-44
//
9-45
std::string generate_name(const std::string& name, const std::string& prefix) {
std::string result = name;
auto iter = result.begin();
for (const auto& c : prefix) {
iter = result.insert(iter, c) + 1;
}
return result;
}
9-46
std::string generate_name(const std::string& name, const std::string& prefix) {
std::string result = name;
result.insert(0, prefix.c_str(), prefix.size());
return result;
}
9-47
int main() {
string s("ab2c3d7R4E6"), numbers("0123456789");
int pos = 0;
cout << "search number" << endl;
while ((pos = s.find_first_of(numbers, pos)) != string::npos) {
cout << s[pos++] << endl;
}
cout << "search alpha" << endl;
pos = 0;
while ((pos = s.find_first_not_of(numbers, pos)) != string::npos) {
cout << s[pos++] << endl;
}
}
9-48
返回string::npos
9-49
std::string longest_noender(const string& in) {
auto it = in.begin();
string result;
string::const_iterator start = in.end(), end = in.end();
while (it != in.end()) {
switch (*it) {
case 'd':
case 'f':
case 'p':
case 'g':
case 'b':
case 'h':
case 'i':
case 'j':
case 'k':
case 'l':
case 'q':
case 't':
case 'y':
if (start != end) {
string tmp(start, end);
if (tmp.length() > result.length()) {
result = tmp;
}
start = it + 1;
end = start;
}
break;
default:
if (start == end) {
start = it;
end = it + 1;
} else {
end = it + 1;
}
}
it++;
}
return result;
}
9-50
double str_sum(const vector<string>& s) {
double sum;
for (const auto& v : s) {
sum += stold(v);
}
return sum;
}
9-51
static unordered_map<string, unsigned int> map_months{
{"January", 1}, {"February", 2}, {"March", 3}, {"April", 4},
{"May", 5}, {"June", 6}, {"July", 7}, {"August", 8},
{"September", 9}, {"October", 10}, {"November", 11}, {"December", 12},
};
static unordered_map<string, unsigned int> map_short_months{
{"Jan", 1}, {"Feb", 2}, {"Mar", 3}, {"Apr", 4}, {"May", 5}, {"Jun", 6},
{"Jul", 7}, {"Aug", 8}, {"Sep", 9}, {"Oct", 10}, {"Nov", 11}, {"Dec", 12}};
class MyDate {
private:
unsigned int year;
unsigned int month;
unsigned int day;
public:
MyDate(unsigned int year, unsigned int month, unsigned int day)
: year(year), month(month), day(day) {}
static MyDate from_str(const string& in) {
vector<string> values;
vector<char> seperators;
auto it = in.begin();
auto beg = in.end(), end = in.end();
while (it != in.end()) {
switch (*it) {
case ' ':
case ',':
case '/':
seperators.push_back(*it);
values.emplace_back(beg, end);
beg = it + 1;
end = beg;
break;
default:
if (beg == end) {
beg = it;
}
end = it + 1;
}
it++;
}
if (beg != end) {
values.emplace_back(beg, end);
}
if (seperators[0] == ' ' && seperators[1] == ',') {
return {(unsigned int)(stoul(values[2])),
(unsigned int)(stoul(values[1])), map_months[values[0]]};
} else if (seperators[0] == '/' && seperators[1] == '/') {
return {(unsigned int)(stoul(values[2])),
(unsigned int)(stoul(values[1])),
(unsigned int)(stoul(values[0]))};
} else if (seperators[0] == ' ' && seperators[1] == ' ') {
return {(unsigned int)(stoul(values[2])),
(unsigned int)(stoul(values[1])),
map_short_months.at(values[0])};
}
throw new runtime_error("unexpeted date string");
};
friend ostream& operator<<(ostream& out, const MyDate& date) {
out << "year: " << date.year << ", month: " << date.month
<< ", day: " << date.day;
return out;
}
};
9-52
int calc_expr(const string& expr) {
stack<string> t;
int result;
auto it = expr.begin();
auto beg = expr.begin(), end = expr.begin();
while (it != expr.end()) {
if (*it >= '0' && *it <= '9') {
if (beg == end) {
beg = it;
end = it + 1;
} else {
end = it + 1;
}
} else if (*it != ' ') {
if (beg != end) {
t.emplace(beg, end);
beg = it + 1;
end = beg;
}
if (*it == ')') {
} else {
t.emplace(1, *it);
}
}
it++;
}
if (beg != end) {
// TODO
// t.emplace(beg, end);
}
while (!t.empty()) {
cout << t.top() << endl;
t.pop();
}
return result;
}
第十章
10-1
int main() {
vector<int> v = {1, 2, 3, 4, 5, 2};
int count = ::count(v.begin(), v.end(), 2);
cout << count << endl;
}
10-2
int main() {
vector<string> v = {"hello", "hola", "hello"};
int count = ::count(v.begin(), v.end(), "hello");
cout << count << endl;
}
10-3
int main() {
vector<int> v{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int sum = accumulate(v.begin(), v.end(), 0);
cout << sum << endl;
}
10-4
精度丢失问题,改为accmulate(v.cbegin(),v.cend(),0.0)
10-5
也是可以执行,我理解是直接比较了const char*
的地址
10-6
int main() {
vector<int> v;
v.resize(10);
fill_n(v.begin(), 10, 0);
for (const auto& n : v) {
cout << n << endl;
}
}
10-7
(a) 修改为copy(lst.cbegin(), lst.cend(), back_inserter(vec));
泛型算法并不会去执行容器操作
(b) 修改为vec.resize(10);
泛型算法不会修改容器的 size
10-9
void elim_dups(std::vector<string>& words) {
sort(words.begin(), words.end());
auto it = unique(words.begin(), words.end());
words.erase(it, words.end());
}
int main() {
std::vector<string> words = {"fox", "jumps", "over", "quick",
"red", "slow", "the", "turtle"};
elim_dups(words);
for (const auto& s : words) {
cout << s << endl;
}
}
10-11
bool is_shorter(const string& s1, const string& s2) {
return s1.size() < s2.size();
}
void elim_dups(std::vector<string>& words) {
stable_sort(words.begin(), words.end(), is_shorter);
auto it = unique(words.begin(), words.end());
words.erase(it, words.end());
}
int main() {
std::vector<string> words = {"fox", "jumps", "over", "quick",
"red", "slow", "the", "turtle"};
elim_dups(words);
for (const auto& s : words) {
cout << s << endl;
}
}
10-13
bool is_longer_then_5(const string& s) { return s.size() >= 5; }
int main() {
//
vector<string> v{"fox", "jumps", "over", "quick",
"red", "slow", "the", "turtle"};
auto it = partition(v.begin(), v.end(), is_longer_then_5);
v.erase(it, v.end());
for (const auto& s : v) {
cout << s << endl;
}
}
10-14
int main() {
auto my_max = [](int a, int b) -> int { return a > b ? a : b; };
cout << my_max(2, 3) << endl;
}
10-15
int main() {
auto create_adder = [](int a) -> std::function<int(int)> {
return [a](int b) -> int { return a + b; };
};
auto adder = create_adder(1);
cout << adder(3) << endl;
}
10-16
int main() {
auto biggies = [](vector<string>& words, vector<string>::size_type sz) {
sort(words.begin(), words.end());
auto it = unique(words.begin(), words.end());
words.erase(it, words.end());
stable_sort(words.begin(), words.end(),
[](const string& a, const string& b) {
return a.size() < b.size();
});
auto wc = find_if(words.begin(), words.end(),
[sz](const string& a) { return a.size() >= sz; });
auto count = words.end() - wc;
cout << count << endl;
};
vector<string> words{"fox", "jumps", "over", "quick",
"red", "slow", "the", "turtle"};
biggies(words, 5);
}
10-20
int main() {
vector<string> words{"fox", "jumps", "over", "quick",
"redredred", "slow", "the", "turtle"};
auto c = count_if(words.begin(), words.end(),
[](const string& s) -> bool { return s.size() > 6; });
cout << c << endl;
}
10-21
int main() {
int i = 5;
auto dec = [&i]() {
if (i <= 0)
return false;
i--;
return true;
};
while (dec()) {
cout << i << endl;
}
}
10-22
int main() {
vector<string> words{"fox", "jumps", "over", "quick",
"redredred", "slow", "the", "turtle"};
auto count_size = [](const vector<string>& v,
const vector<string>::size_type size) -> int {
return count_if(v.begin(), v.end(), [size](const string& s) -> bool {
return s.size() >= size;
});
};
auto count_size_5 = bind(count_size, placeholders::_1, 5);
cout << count_size_5(words) << endl;
}
10-23
29 个参数
10-24
int main() {
vector<int> sizes{1, 2, 3, 4, 5, 6, 7, 8};
string s("helo");
auto it = find_if(sizes.begin(), sizes.end(),
[&s](int size) -> bool { return size > s.size(); });
cout << (it == sizes.end() ? "not found" : ::to_string(*it)) << endl;
}
10-26
对迭代器进行复制时,进行的容器操作不同push_front
,push_back
,insert
10-27
int main() {
vector<int> sizes{1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 5, 6, 6, 6, 6}, result;
unique_copy(sizes.begin(), sizes.end(), back_inserter(result));
for (const auto& n : result) {
cout << n << endl;
}
}
10-28
int main() {
vector<int> sizes{1, 2, 3, 4, 5, 6, 7, 8, 9};
deque<int> result1, result2, result3;
copy(sizes.begin(), sizes.end(), inserter(result1, result1.begin()));
copy(sizes.begin(), sizes.end(), back_inserter(result2));
copy(sizes.begin(), sizes.end(), front_inserter(result3));
cout << "result 1:" << endl;
for (const auto& n : result1) {
cout << n << endl;
}
cout << "result 2:" << endl;
for (const auto& n : result2) {
cout << n << endl;
}
cout << "result 3:" << endl;
for (const auto& n : result3) {
cout << n << endl;
}
}
10-29
int main() {
auto ifs = ifstream("in.txt", ios_base::in);
vector<string> res{};
istream_iterator<string> isi(ifs), eof;
while (isi != eof) {
res.emplace_back(*(isi++));
}
for (const auto& n : res) {
cout << n << endl;
}
}
10-30
int main() {
istream_iterator<int> in_iter(cin), eof;
vector<int> result{};
copy(in_iter, eof, back_inserter(result));
sort(result.begin(), result.end());
for (const auto& n : result) {
cout << n << endl;
}
}
10-31
int main() {
istream_iterator<int> in_iter(cin), eof;
vector<int> result{};
unique_copy(in_iter, eof, back_inserter(result));
sort(result.begin(), result.end());
for (const auto& n : result) {
cout << n << endl;
}
}
10-33
int main(int argc, const char** argv) {
if (argc < 4) {
cerr << "args not enough" << endl;
return -1;
}
auto inf = ifstream(argv[1], ios_base::in);
auto outf1 = ofstream(argv[2], ios_base::trunc | ios_base::out);
auto outf2 = ofstream(argv[3], ios_base::trunc | ios_base::out);
istream_iterator<int> isi(inf), eof;
ostream_iterator<int> osi1(outf1, " "), osi2(outf2, " ");
partition_copy(isi, eof, osi1, osi2,
[](int x) -> bool { return x % 2 == 0; });
}
10-.34
int main() {
vector<int> v{1, 2, 3, 4, 5};
for (auto it = v.rbegin(); it != v.rend(); it++) {
cout << *it << endl;
}
return 0;
}
10-35
int main() {
vector<int> v{1, 2, 3, 4, 5};
auto it = v.end();
do {
it--;
cout << *it << endl;
} while (it != v.begin());
return 0;
}
10-36
int main() {
vector<int> v{1, 2, 3, 0, 4, 0, 5};
auto it = find(v.rbegin(), v.rend(), 0);
cout << *(it + 1) << " " << *it << " " << *(it - 1) << endl;
return 0;
}
10-37
int main() {
vector<int> v{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
list<int> l;
copy(v.rbegin() + 3, v.rbegin() + 7, back_inserter(l));
for (const auto& n : l) {
cout << n << endl;
}
return 0;
}
10-39
list 上的迭代器属于双向迭代器,vector 上的迭代器属于随机访问迭代器
第十一章
11-3
int main() {
unordered_map<string, unsigned int> counter;
vector<string> words{"The", "But", "And", "Or", "An", "A",
"The", "But", "And", "or", "an", "a"};
for (const auto& word : words) {
counter[word]++;
}
for (const auto& pair : counter) {
cout << pair.first << " -> " << pair.second << endl;
}
}
11-4
int main() {
unordered_map<string, unsigned int> counter;
vector<string> words{"The", "But", "And", "Or", "An", "A",
"The", "But", "And", "or", "an", "a"};
for (const auto& word : words) {
string key;
transform(word.begin(), word.end(), back_inserter(key),
[](unsigned char c) { return tolower(c); });
counter[key]++;
}
for (const auto& pair : counter) {
cout << pair.first << " -> " << pair.second << endl;
}
}
11-9
int main() {
map<string, list<unsigned int>> m;
return 0;
}
11-10
前者可以,后者不行,因为 list<int>::iterator 没有实现<=运算符
11-15
mappedtype 为 vector<int>,keytype 为 int,value_type 为 pair<int,vector<int>>
11-16
int main() {
map<int, int> m{{1, 2}};
auto it = m.begin();
it->second = 3;
for (const auto& pair : m) {
cout << pair.first << " " << pair.second << endl;
}
return 0;
}
11-17
- 合法
- 不合法,multiset 上没有
push_back
的方法 - 合法
- 合法
11-28
int main() {
map<string, vector<int>> m{{"a", {1, 2, 3, 4}}, {"b", {5, 6, 7, 8}}};
auto it = m.find("a");
for (const auto& item : it->second) {
cout << item << endl;
}
}
11-29
前两者返回 end,后者返回 pair{end,end}
11-33
#include <fstream>
#include <ios>
#include <iostream>
#include <map>
#include <sstream>
#include <string>
using namespace std;
int main() {
ifstream dict_if("./1.txt", ios_base::in), text_if("./2.txt", ios_base::in);
map<string, string> dict;
string tmp;
stringstream result_ss;
while (getline(dict_if, tmp)) {
auto it = tmp.find(' ');
dict.insert({tmp.substr(0, it), tmp.substr(it + 1)});
}
while (text_if >> tmp) {
if (dict.find(tmp) != dict.end()) {
tmp = dict[tmp];
}
result_ss << tmp << " ";
}
cout << result_ss.str() << endl;
}
11-34
下标会在 key_type 不存在时,自动创建,find 不会
11-35
insert 不会生效,因为相同的 key_type 已经存在
第十二章
12-6
#include <iostream>
#include <iterator>
#include <vector>
using namespace std;
auto foo1() -> vector<int>* {
auto v = new vector<int>();
istream_iterator<int> in(cin), eof;
while (in != eof) {
v->emplace_back(*in);
in++;
}
return v;
}
auto foo2(vector<int>* v) {
for (const auto& n : *v) {
cout << n << endl;
}
}
int main() {
auto p = foo1();
foo2(p);
delete p;
}
12-7
#include <iostream>
#include <iterator>
#include <memory>
#include <vector>
using namespace std;
auto foo1() -> shared_ptr<vector<int>> {
auto v = make_shared<vector<int>>();
istream_iterator<int> in(cin), eof;
while (in != eof) {
v->emplace_back(*in);
in++;
}
return v;
}
auto foo2(shared_ptr<vector<int>> v) {
for (const auto& n : *v) {
cout << n << endl;
}
}
int main() {
auto p = foo1();
foo2(p);
}
12-8
无错误,存在指针类型向 bool 的隐式类型转换
12-10
应该没啥问题
12-11
会导致资源指针被 delete 两次
12-12
a、c 合法,b 会导致内存泄露,d 中的 p 会被自动 delete
12-13
会导致 p 被 delete 了两次
12-14
#include <iostream>
#include <memory>
using namespace std;
using connection = int;
void disconnect(connection* c) { cout << "disconnected" << endl; }
int main() {
connection conn_id = 1;
auto sp = shared_ptr<connection>(&conn_id, disconnect);
return 0;
}
12-15
#include <iostream>
#include <memory>
using namespace std;
using connection = int;
int main() {
connection conn_id = 1;
auto sp = shared_ptr<connection>(
&conn_id, [](connection* conn) { cout << "disconnected" << endl; });
return 0;
}
12-16
将 unique_ptr 的赋值构造函数重载为 delete
12-17
a、b、d、f 有问题
a 传入参数类型不对,需要 int*
b、d 导致栈上的地址被 delete
f 导致 double delete
12-18
shared_ptr 上的引用计数不一定为 1,不能移交所有权
12-23
#include <cstddef>
#include <cstring>
#include <iostream>
#include <memory>
using namespace std;
unique_ptr<char[]> str_concat(const char* s1, const char* s2) {
size_t len1 = strlen(s1), len2 = strlen(s2);
unique_ptr<char[]> str(new char[len1 + len2 + 1]);
memcpy(str.get(), s1, len1);
memcpy(str.get() + len1, s2, len2);
str[len1 + len2] = '\0';
return str;
}
int main() {
const char* s1 = "hello ";
const char* s2 = "cattchen";
auto p = str_concat(s1, s2);
cout << p.get() << endl;
}
12-25
delete [] pa;
12-26
#include <cstddef>
#include <iostream>
#include <memory>
using namespace std;
const size_t N = 5;
int main() {
allocator<string> alloc;
auto p = alloc.allocate(N);
string s;
string* q = p;
while (cin >> s && q != p + N)
alloc.construct(q++, s);
const size_t size = q - p;
alloc.deallocate(p, N);
}
12-28
#include <cstddef>
#include <fstream>
#include <iostream>
#include <iterator>
#include <map>
#include <sstream>
#include <vector>
using namespace std;
int main() {
vector<string> lines;
multimap<string, size_t> dict;
ifstream in("./1.txt");
string tmp, word;
size_t line = 0;
while (getline(in, tmp)) {
stringstream ss(tmp);
lines.push_back(tmp);
while (ss >> word) {
dict.insert({word, line});
}
++line;
}
while (cin >> tmp) {
cout << "element occurs " << dict.count(tmp) << " times" << endl;
auto r = dict.equal_range(tmp);
for (auto it = r.first; it != r.second; it++) {
cout << "(line " << (it->second + 1) << ") " << lines[it->second]
<< endl;
}
}
}
第十三章
13-1
拷贝构造函数的第一个参数是自身类型的引用
13-12
要发生三次析构函数调用,一次是形参,两次是局部变量
13-14
都显示相同的序号,因为合成拷贝构造函数会直接复制序号,导致 a、b、c 序号相同
#include <iostream>
using namespace std;
static int global_id = 0;
class numbered {
public:
int id;
numbered() : id(++global_id){};
};
void f(numbered s) { cout << s.id << endl; }
int main() {
numbered a, b = a, c = b;
f(a);
f(b);
f(c);
}
13-15
会,但是 f 显示的不是对应的序号,而是新序号。函数调用进行值传递,复制了 numbered
13-16
显示预期的结果,因为是引用传递
13-18
#include <iostream>
using namespace std;
static int global_id = 0;
class Employee {
public:
int id;
string name;
Employee(const string& n) : id(global_id++), name(n) {}
};
int main() {}
13-19
不需要定义自己的拷贝控制成员,因为 int 和 string 可以直接复制
13-27
#include <iostream>
#include <string>
using namespace std;
class HasPtr {
private:
string* sp;
unsigned int* reference_count;
public:
HasPtr() : sp(new string()), reference_count(new unsigned int(1)) {}
HasPtr(const string& s)
: sp(new string(s)), reference_count(new unsigned int(1)) {}
HasPtr(const HasPtr& hp)
: sp(new string(*hp.sp)), reference_count(hp.reference_count) {
(*hp.reference_count)++;
}
HasPtr& operator=(const HasPtr& hp) {
(*hp.reference_count)++;
this->sp = hp.sp;
this->reference_count = hp.reference_count;
return *this;
}
~HasPtr() {
(*reference_count)--;
if (*reference_count <= 0) {
delete reference_count;
delete sp;
}
}
unsigned int const use_count() { return *this->reference_count; }
};
int main() {
//
HasPtr hp("hello"), hp2 = hp;
cout << hp.use_count() << endl << hp2.use_count() << endl;
}
13-29
发生了函数重载,函数签名不一致,并不是同一个函数
13-30
#include <iostream>
#include <string>
using namespace std;
class HasPtr {
private:
string* sp;
unsigned int* reference_count;
public:
friend void swap(HasPtr& hpa, HasPtr& hpb) {
cout << "swap" << endl;
swap(hpa.reference_count, hpb.reference_count);
swap(hpa.sp, hpb.sp);
};
HasPtr() : sp(new string()), reference_count(new unsigned int(1)) {}
HasPtr(const string& s)
: sp(new string(s)), reference_count(new unsigned int(1)) {}
HasPtr(const HasPtr& hp)
: sp(new string(*hp.sp)), reference_count(hp.reference_count) {
(*hp.reference_count)++;
}
HasPtr& operator=(HasPtr hp) {
swap(*this, hp);
return *this;
}
~HasPtr() {
(*reference_count)--;
if (*reference_count <= 0) {
delete reference_count;
delete sp;
}
}
unsigned int const use_count() { return *this->reference_count; }
};
int main() {
HasPtr hp("hello"), hp2;
hp2 = hp;
cout << hp.use_count() << endl << hp2.use_count() << endl;
}
13-31
#include <algorithm>
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class HasPtr {
private:
string* sp;
unsigned int* reference_count;
public:
friend void swap(HasPtr& hpa, HasPtr& hpb) {
// cout << "swap" << endl;
swap(hpa.reference_count, hpb.reference_count);
swap(hpa.sp, hpb.sp);
};
HasPtr() : sp(new string()), reference_count(new unsigned int(1)) {}
HasPtr(const string& s)
: sp(new string(s)), reference_count(new unsigned int(1)) {}
HasPtr(const HasPtr& hp)
: sp(new string(*hp.sp)), reference_count(hp.reference_count) {
(*hp.reference_count)++;
}
HasPtr& operator=(HasPtr hp) {
swap(*this, hp);
return *this;
}
~HasPtr() {
(*reference_count)--;
if (*reference_count <= 0) {
delete reference_count;
delete sp;
}
}
bool operator<(const HasPtr& hp) {
return *(this->sp) < *hp.sp;
return true;
}
friend ostream& operator<<(ostream& out, const HasPtr& hp) {
return out << (*hp.sp);
}
unsigned int const use_count() { return *this->reference_count; }
};
int main() {
vector<HasPtr> v{{"hello"}, {"cattchen"}, {"asdf"}};
sort(v.begin(), v.end());
for (const auto& item : v) {
cout << item << endl;
}
}
第十四章
14-34
#include <iostream>
using namespace std;
class Foo {
public:
int operator()(bool condition, int a, int b) { return condition ? a : b; }
};
int main() {
Foo f;
cout << f(1 < 2, 1, 2) << endl << f(1 > 2, 1, 2) << endl;
}
14-35
#include <iostream>
#include <string>
using namespace std;
class InputString {
public:
InputString(istream& in = cin) : in(in) {}
string const operator()() const {
string tmp;
getline(in, tmp);
return tmp;
}
private:
istream& in;
};
int main() {
InputString is;
cout << is() << endl;
return 0;
}
14-36
#include <iostream>
#include <string>
#include <vector>
using namespace std;
class InputString {
public:
InputString(istream& in = cin) : in(in) {}
string const operator()() const {
string tmp;
getline(in, tmp);
return tmp;
}
private:
istream& in;
};
int main() {
InputString is;
string tmp;
vector<string> v;
while (!(tmp = is()).empty()) {
v.push_back(tmp);
}
for (const auto& item : v) {
cout << item << endl;
}
return 0;
}
14-37
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
class Point {
private:
int x, y;
public:
Point(int x, int y) : x(x), y(y) {}
Point() : Point(0, 0) {}
friend ostream& operator<<(ostream& out, const Point& p) {
return out << "Point {x: " << p.x << ", y: " << p.y << "}";
}
friend bool operator==(const Point& pa, const Point& pb) {
return pa.x == pb.x && pa.y == pb.y;
}
};
int main() {
vector<Point> v{{0, 0}, {1, 2}, {1, 1}, {0, 0}, {1, 1}};
v.erase(remove(v.begin(), v.end(), Point{1, 1}), v.end());
for (const auto& item : v) {
cout << item << endl;
}
}
14-47
前者表示将Integral
转为const int
,后者表示这是常对象的函数
第十六章
16-2
#include <iostream>
using namespace std;
template <typename T> bool compare(const T& a, const T& b) {
if (less<T>()(a, b))
return -1;
if (less<T>()(b, a))
return 1;
return 0;
}
int main() {
cout << compare(1, 2) << endl;
return 0;
}
16-4
#include <iostream>
#include <vector>
using namespace std;
template <typename Iter, typename Value>
Iter my_find(const Iter& begin, const Iter& end, const Value& value) {
for (Iter it = begin; it != end; it++) {
if (*it == value) {
return it;
}
}
return end;
};
int main() {
vector<int> v{3, 4, 2, 5, 1};
auto it = my_find(v.begin(), v.end(), 2);
cout << *it << endl;
return 0;
}
16-5
#include <cstddef>
#include <iostream>
using namespace std;
template <typename Value, unsigned Size> void print(const Value (&arr)[Size]) {
for (size_t i = 0; i < Size; i++) {
cout << arr[i] << endl;
}
}
int main() {
int arr[3] = {2, 3, 4};
print(arr);
return 0;
}
16-6
#include <iostream>
using namespace std;
template <typename Type, unsigned Size>
const Type* my_begin(const Type (&arr)[Size]) {
return &arr[0];
}
template <typename Type, unsigned Size>
const Type* my_end(const Type (&arr)[Size]) {
return &arr[Size];
}
int main() {
int arr[3] = {1, 2, 3};
for (auto it = my_begin(arr); it != my_end(arr); it++) {
cout << *it << endl;
}
}
16-7
#include <cstddef>
#include <iostream>
using namespace std;
template <typename Type, unsigned Size>
size_t get_size(const Type (&arr)[Size]) {
return Size;
}
int main() {
int arr[3] = {1, 2, 3};
cout << get_size(arr) << endl;
return 0;
}
16-11
template <typename elemType> class ListItem;
template <typename elemType> class List {
public:
List<elemType>();
List<elemType>(const List<elemType>&);
List<elemType>& operator=(const List<elemType>&);
void insert(ListItem<elemType>* prt, elemType value);
private:
ListItem<elemType>*front, *end;
};
16-14
template <typename SizeType> class Screen {
private:
SizeType width;
SizeType height;
public:
Screen(SizeType width, SizeType height) : width(width), height(height){};
Screen() : Screen(0, 0) {}
};
16-19
#include <iostream>
#include <vector>
using namespace std;
template <typename Container> void print(const Container& c) {
for (typename Container::size_type i = 0; i < c.size(); i++) {
std::cout << c[i] << std::endl;
}
}
int main() {
vector<int> v{1, 2, 3, 4, 5};
print(v);
return 0;
}
16-20
#include <iostream>
#include <vector>
using namespace std;
template <typename Container> void print(Container& c) {
for (typename Container::iterator it = c.begin(); it != c.end(); it++) {
std::cout << *it << std::endl;
}
}
int main() {
vector<int> v{1, 2, 3, 4, 5};
print(v);
return 0;
}
16-21
#include <iostream>
class DebugDeleter {
private:
std::ostream& os;
public:
DebugDeleter(std::ostream& out = std::cerr) : os(out) {}
template <typename Pointer> void operator()(Pointer* p) const {
os << "deleting pointer" << std::endl;
delete p;
}
};
int main() {
DebugDeleter d;
auto a = new int;
d(a);
auto b = new double;
d(b);
return 0;
}
16-28
#include <cstddef>
#include <functional>
#include <iostream>
using namespace std;
template <typename Value> class my_shared_ptr {
private:
typedef Value* Pointer;
size_t* const reference_count;
Pointer const pointer;
const std::function<void(Pointer)> del;
public:
my_shared_ptr<Value>(Pointer pointer, std::function<void(Pointer)> deleter)
: pointer(pointer), reference_count(new size_t(1)), del(deleter) {}
my_shared_ptr<Value>(Pointer pointer)
: my_shared_ptr<Value>(pointer, [](Pointer p) { delete p; }) {}
my_shared_ptr<Value>() : my_shared_ptr<Value>(new Value) {}
my_shared_ptr<Value>(const my_shared_ptr<Value>& p)
: reference_count(p.reference_count), pointer(p.pointer), del(p.del) {
(*reference_count)++;
}
~my_shared_ptr<Value>() {
(*reference_count)--;
if (*reference_count <= 0) {
del(pointer);
}
delete reference_count;
}
Pointer operator->() const { return pointer; }
Value operator*() const { return *pointer; }
};
int main() {
auto sp = my_shared_ptr<int>(new int(10), [](int* p) {
delete p;
cout << "destrcted" << endl;
});
cout << *sp << endl;
}
16-53
#include <iostream>
using namespace std;
template <typename T> void print(const T& value) { cout << value << endl; }
template <typename T, typename... Args>
void print(const T& value, const Args&... args) {
cout << value << endl;
if (sizeof...(args)) {
print(args...);
}
}
int main() {
//
print(1);
print(2, 3);
print(4, 5, 6);
}
第十七章
17-1
#include <iostream>
#include <tuple>
using namespace std;
int main() {
auto p = make_tuple(10, 20, 30);
cout << get<0>(p) << endl;
cout << get<1>(p) << endl;
cout << get<2>(p) << endl;
return 0;
}
17-2
#include <iostream>
#include <map>
#include <string>
#include <tuple>
#include <vector>
using namespace std;
int main() {
tuple<string, vector<string>, pair<string, int>> p;
return 0;
}
17-10
#include <bitset>
#include <iostream>
using namespace std;
int main() {
bitset<32> bitvec1(0b100000001000010010111), bitvec2;
cout << bitvec1 << endl;
bitvec2.set(0);
bitvec2.set(1);
bitvec2.set(2);
bitvec2.set(4);
bitvec2.set(7);
bitvec2.set(12);
bitvec2.set(20);
cout << bitvec2 << endl;
}
17-28
#include <iostream>
#include <random>
using namespace std;
unsigned int random_number() {
static default_random_engine dre;
static uniform_int_distribution<unsigned int> uid(1, 100);
return uid(dre);
}
int main() {
cout << random_number() << endl;
cout << random_number() << endl;
cout << random_number() << endl;
}
17-30
#include <iostream>
#include <random>
using namespace std;
unsigned int random_number(int seed = default_random_engine::default_seed,
unsigned int min = 0, unsigned int max = 100) {
static default_random_engine dre(seed);
static uniform_int_distribution<unsigned int> uid(min, max);
return uid(dre);
}
int main() {
cout << random_number() << endl;
cout << random_number() << endl;
cout << random_number() << endl;
}
第十九章
19-1
#include <cstddef>
#include <cstdlib>
#include <iostream>
#include <new>
using namespace std;
void* operator new(size_t size) {
void* mem;
if ((mem = malloc(size)) != NULL) {
cout << "new called" << endl;
return mem;
}
throw std::bad_alloc();
}
void operator delete(void* mem) noexcept { free(mem); }
int main() {
auto p = new int;
*p = 123;
}
19-12
#include <iostream>
#include <string>
class Screen {
public:
typedef std::string::size_type pos;
char get_cursor() const { return contents[cursor]; }
char get() const;
char get(pos ht, pos wd) const;
public:
std::string contents;
pos cursor;
pos height, width;
};
int main() {
using namespace std;
auto pdata = &Screen::cursor;
Screen s;
auto cursor = s.*pdata;
}