c++ primer 书代码学习

c++ primer 书代码学习,第1张

c++ primer 书代码学习
#include 
#include 

using namespace std;
class Sales_item
{
	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:
	Sales_item() = default;
	Sales_item(const std::string& book): bookNo(book){}
	Sales_item(std::istream& is){is >> *this; }
public:
	Sales_item& operator+=(const Sales_item&);
	std::string isbn() const { return bookNo; }
	double avg_price() const;
private:
	std::string bookNo;
	unsigned units_sold = 0;
	double revenue = 0.0; 
public:
};

inline bool compareIsbn(const Sales_item& lhs, const Sales_item& rhs)
{
	return lhs.isbn() == rhs.isbn();
}

Sales_item operator+(const Sales_item&,const Sales_item&);

inline bool operator==(const Sales_item& lhs,const Sales_item& rhs)
{
	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);
}

Sales_item& Sales_item::operator+=(const Sales_item& rhs)
{
	units_sold += rhs.units_sold;
	revenue += rhs.revenue;
	return *this;
}

Sales_item operator+(const Sales_item& lhs,const Sales_item& rhs)
{
	Sales_item ret(lhs);
	ret += rhs;
	return ret;
}

std::istream& operator>>(std::istream& in, Sales_item& s)
{
	double price;
	in>>s.bookNo>>s.units_sold>>price;
	if(in)
		s.revenue = s.units_sold * price;
	else
		s = Sales_item();
	return in;
}

std::ostream& operator<<(std::ostream& out,const Sales_item& s)
{
	out<
#include 

class Sales_data
{
	friend Sales_data add(const Sales_data&, const Sales_data&);
	friend std::ostream &print(std::ostream&, const Sales_data&);
	friend std::istream &read(std::istream&, Sales_data&);
public:
	// 构造函数
	Sales_data() = default;
	Sales_data(const std::string &s):bookNo(s){}
	Sales_data(const std::string &s, unsigned n, double p):
			   bookNo(s),units_sold(n),revenue(p*n){}
	Sales_data(std::istream &);

	// 对 Sales_data 对象的 *** 作
	std::string isbn() const { return bookNo; }
	Sales_data& combine(const Sales_data&);
	double avg_price() const;
private:
public:
	std::string bookNo;
	unsigned units_sold = 0;
	double revenue = 0.0;
};

// 非成员 Sales_data 接口函数
Sales_data add(const Sales_data&, const Sales_data&);
std::ostream &print(std::ostream&, const Sales_data&);
std::istream &read(std::istream&, Sales_data&);

// bool compareIsbn(const Sales_data &lhs,const Sales_data &rhs)
// {
// 	return lhs.isbn() < rhs.isbn();
// }

Sales_data::Sales_data(std::istream &is)
{
	// read 会将事务从 is 读取到此对象中
	read(is, *this);
}

double Sales_data::avg_price() const
{
	if(units_sold)
		return revenue / units_sold;
	else
		return 0;
}

// 将给定 Sales_data 的值添加到此对象中
Sales_data& Sales_data::combine(const Sales_data &rhs)
{
	units_sold += rhs.units_sold; //将 rhs 的成员添加到
	revenue += rhs.revenue; // “this”对象的成员
	return *this; // 返回调用函数的对象
}

Sales_data add(const Sales_data& lhs, const Sales_data &rhs)
{
	Sales_data sum = lhs;// 将数据成员从 lhs 复制到 sum
	sum.combine(rhs);//将 rhs 中的数据成员添加到 sum
	return sum;	
}

// 交易包含 ISBN、售出的副本数量和销售价格
istream& read(istream &is, Sales_data &item)
{
	double price = 0;
	is >> item.bookNo>>item.units_sold>>price;
	item.revenue = price * item.units_sold;
	return is;
}

ostream& print(ostream &os, const Sales_data &item)
{
	os << item.isbn()<<" "< 1)
		ret *= val--;
	// 将 ret * val 赋值给 ret 并递减 val
	return ret;
	// 返回结果
}

// 阶乘的递归版本:
// 计算 val!,即 1 * 2 * 3 。 . . * 价值
int factorial(int val)
{
	if(val > 1)
		return factorial(val - 1) * val;
	return 1;
}

inline string make_plural(size_t ctr, const string& word,
							   const string& ending)
{
	return (ctr > 1) ? word + ending : word;
}


#if 0
//每个 C++程序都包含一个或多个函数 〈function),其中一个必须命名为 main。 *** 作
//系统通过调用 main 来运行 C++程序。下面是一个非常简单的 main 函数, 它什么也不干,
//只是返回给 *** 作系统一个值:
int main()
{
	return 0;
}


//在书店程序中,我们需要将多条记录合并成单一的汇总记录。作为一个相关的,但更
//简单的问题,我们先来看一下如何将两个数相加。通过使用 IO 库,我们可以扩展 main
//程序,使之能提示用户输入两个数,然后输出它们的和:

#include 
int main()
{
	std::cout<<"Enter two numbers:"<>v1>>v2;
	std::cout<<"The sum of "<
using namespace std;

int main()
{
	cout<<"Hello,World"<

int main()
{
	std::cout<<"Enter two numbers: "<>v1>>v2;
	std::cout<<"The sum of "<
int main()
{
	int sum = 0,val = 0;
	// 只要val 的值小于等于10,while 循环就会持续执行
	while(val <= 10)
	{
		sum += val; // 将sum + val 赋予 sum
		++val; // 将val 加1
	}
	std::cout<<"Sum of 1 and 10 inclusive is "<
int main()
{
	int sum = 0;
	for(int i = -100; i<=100;++i)
	{
		sum += i;
	}
	std::cout<
int main()
{
	int sum = 0,value = 0;
	// 读取数据直到遇到文件尾,计算所有读入的值的和
	while(std::cin>>value)
	{
		sum += value;
	}
	std::cout<<"Sum is: "<

int main()
{
	 currVal 是我们正在统计的数; 我们将读入的新值存入 val
	int currVal = 0,val = 0;
	// 读取第一个数,并确保确实有数据可以处理
	if(std::cin >> currVal)
	{
		int cnt = 1; //保存我们正在处理的当前值的个数
		while(std::cin>>val) //读取剩余的数
		{
			if(val == currVal) //如果值相同
				++cnt;
			else
			{
				//和否则,打印前一个值的个数
				std::cout<
int main()
{
	Sales_item book;
	// 读入 TSBN 号、售出的册数以及销售价格
	std::cin>>book;
	// 写入ISBN、售出的册数、总销售额和平均价格
	std::cout<
int main()
{
	Sales_item item1,item2;
	std::cin>>item1>>item2;
	std::cout<
int main()
{
	Sales_item item1,item2;
	std::cin>>item1>>item2;
	// 首先检查 iteml 和 item2 是否表示相同的书
	if(item2.isbn() == item1.isbn())
	{
		std::cout<
int main()
{
	Sales_item total;// 保存下一条交易记录的变量
	// 读入第一条交易记录,并确保有数据可以处理
	if(std::cin>>total)
	{
		Sales_item trans;// 保存和的变量
		// 读入并处理剩余交易记录
		while(std::cin>>trans)
		{
			// 如果我们仍在处理相同的书
			if(total.isbn() == trans.isbn())
				total += trans; //更新总销售额
			else
			{
				// 打印前一本书的结果
				std::cout<
int main()
{
	int i = 42;
	std::cout<
int main()
{
	unsigned u = 10,u2 = 42;
	std::cout<= 0)
	{
		std::cout<= 0; --i)
	{
		std::cout< 0)
	{
		--u;
		std::cout<
int main()
{
	std::cout<<"Hello World!";
	std::cout<<"";

	std::cout<<"nCCtoptionstfile.[cC]n";

	std::cout<<"a really,really long string literal "
			   "that spans two lines"<>s                 从 is 中读取字符串赋给 s,字符串以空白分隔,返回 is
//getline(is,s)     从 is 中读取一行赋给 s,返回 is
//s.empty ()            s 为空返回 true,和否则返回 false
//s.size()           返回 s 中字符的个数
//sr[n]               返回 s 中第 n 个字符的引用,位置n 从0 计起
//s1+s2              返回 sl 和 s2 连接后的结果
//sl=s2                 用 s2 的副本代替 sl 中原来的字符
//s1==s2                如果 sl 和 s2 中所含的字符完全一样,则它们相等,string 对象的相
//s1!=s2             等性判断对字母的大小写敏感
//<,<=,>,>=       利用字符在字典中的顺序进行比较,且对字母的大小写敏感
#include 
#include 
using namespace std;
int main()
{
	string s;
	cin>>s;
	cout<>s1>>s2;  把第一个输入读到 sl 中,第二个输入读到 s2 中
	cout<
using namespace std;
int main()
{
	string word;
	while(cin>>word)
		cout<>运算符。getline 函数的参数是一个输入流和一个 string 对象,函
//数从给定的输入流中读入内容,直到遇到换行符为止〈注意换行符也被读进来了),然后
//把所读的内容存入到那个 string 对象中去〈注意不存换行符)。get1line 只要一遇到换
//行符就结束读取 *** 作并返回结果,哪怕输入的一开始就是换行符也是如此。如果输入真的
//-开始就是换行符,那么所得的结果是个空 string。

#include 
using namespace std;
int main()
{
	string line;
	//1 每次读入一整行,直至到达文件末尾
	while(getline(cin,line))
	{
		cout<
using namespace std;
int main()
{
	string line;
	while(getline(cin,line))
	{
		if(!line.empty())
		{
			cout<
#include 

using namespace std;
int main()
{
	string line;
	//每次读入一整行,输出其中超过 80 个字符的行
	while(getline(cin,line))
	{
		if(line.size() > 80)
			cout<
#include 
using namespace std;
int main()
{
	string str("the expense of spiritn");
	cout<<"The size of "<
#include 
#include 
using namespace std;

int main()
{
	string s("Hello world!!!");
	//punct_cnt 与 s.size 返回的类型相同
	decltype(s.size()) punct_cnt = 0;
	// 统计s中标点符号的个数
	for(auto c : s) //对于 s 中的每个字符
	{
		if(ispunct(c)) //如果字符是标点符号
			++punct_cnt;//增加标点计数器
	}
	cout<
#include 

using namespace std;

int main()
{
	string str("some string"),orig = str;
	if(!str.empty()) //确保有一个字符要打印
	{ 
		cout<
#include 
#include 
#include 
using namespace std;

int main()
{
	string s1 = "A string example";
	string s2 = "A different string";

	if(s1 < s2)
		cout< sz)
		largeStr[sz-1] = '';
	strncpy(largeStr," ",2);// 迂腐,但好习惯
	strncpy(largeStr,ca2,sz - strlen(largeStr));
	cout<
#include 
#include 

using namespace std;
int main()
{
	const string hexdigits = "0123456789ABCDEF";// 可能的十六进制数字
	cout<<"Enter a series of numbers between 0 and 15"
		<<" separated by spaces.  Hit ENTER when finished: "
		<>n)
		if(n < hexdigits.size()) // 忽略无效输入
			result += hexdigits[n];// 获取指定的十六进制数字

	cout<<"Your hex number is: "< v1    v1 是一个空 vector,它潜在的元素是 T 类型的,执行默认初始化
//Vector v2(v1)          v2 中包含有 v1 所有元素的副本
//vector v2 = v1         等价于 v2 (v1) ,v2 中包含有 vl 所有元素的副本
//Vector v3(n,val)      v3 包含了n 个重复的元素,每个元素的值都是 val
//vector v4(n)            v4 包含了n 个重复地执行了值初始化的对象
//vector v5{a,b,c...} v5包含了初始值个数的元素,每个元素被赋予相应的初始值
//vector v5={a,b,c...} 等价于v5fa,bvc...}
//可以默认初始化 vector 对象 参见 2.2.1 节,第 40 页),从而创建一个指定类型的
//空 vector:
//vector svec;//黑认初始化,svec 不含任何元素
//看起来空 vector 好像没什么用,但是很快我们就会知道程序在运行时可以很高效地往
//vector 对象中添加元素。事实上,最常见的方式就是先定义一个空 vector,然后当运
//行时获取到元素的值后再逐一添加。

//当然也可以在定义 vector 对象时指定元素的初始值。 例如,允许把一个 vector 对
//象的元素拷贝给另外一个 vector 对象。此时,新 vector 对象的元素就是原 vector
//对象对应元素的副本。注意两个 vector 对象的类型必须相同:
//vector ivec; // 初始状态为空
// 在此处给 ivec 添加一些值
//vector ivec2 (ivec)        // 把 ivec 的元素拷贝给 ivec2
//vector ivec3 = ivec;       // 把 ivec 的元素找贝给 ivec3
//vector svec(ivec2);  // 错误: svec 的元素是 String 对象,不是 int

#include 
#include 
#include 
using namespace std;
int main()
{
	vector grades;
	// 以十为一组计算等级数:
	// 0--9, 10--19, . . . 90--99, 100
	unsigned scores[11] = {};// 11个桶,所有值初始化为0
	unsigned grade;
	while(cin >> grade)
	{
		if(grade<=100)
		{
			// 增加当前集群的计数器
			++scores[grade/10];
		}
		grades.push_back(grade);
	}
	cout<<"grades.size = "<
#include 
#include 
using namespace std;


int main()
{
	// 列表初始化,文章有3个元素
	vector articles = {"a","an","the"};

	vector svec; // 默认初始化; svec 没有元素
	vector ivec; // ivec 持有 int 类型的对象
	vector Sales_vec;  // holds Sales_items

	vector> file; //其元素为向量的向量
	vector> vecOfvec; 

	// 所有五个向量的大小都是 0
	cout< ivec2(10); // 十个元素,每个都初始化为 0
	vector ivec3(10,-1);// 十个 int 元素,每个都初始化为 -1
	vector svec2(10);// 十个元素,每个元素都是一个空字符串
	vector svec3(10,"hi"); // 十个字符串; 每个元素都是“嗨!”
	cout< v1(10); // 用十个值初始化的元素构造 v1
	vector v2{10}; //10元素值初始化元素
	vector v3(10,"hi"); // 十个值为“hi”的元素
	// 再次列表初始化不可行,所以普通构造
	vector v4{10,"hi"}; // 十个值为“hi”的元素

	// 所有四个vector的大小都是 10
	cout< vs1{"hi"};// 列表初始化:vs1 有 1 个元素
	vector vs2{10}; // 10默认初始化的元素
	vector vs3{10,"hi"}; // 有十个值为“hi”的元素
	cout< v5(10,1); // 值为 1 的十个元素
	vector v6{10,1}; // 两个元素的值为 10 和 1
	cout< alt_v3 = {10};// 一个值为 10 的元素
	vector alt_v4 = {10,1};// 两个元素的值为 10 和 1
	cout<
#include
#include

using namespace std;

int main()
{
	// 保存我们从标准输入中读取的成绩
	vector grades;

	// 以十为一组计算等级数:
	// 0--9, 10--19, . ..  90--99, 100
	vector scores(11,0);//11 个桶,最初都是 0
	unsigned grade;
	while(cin >> grade) //读取成绩
	{
		if(grade <= 100) // 只处理有效成绩
		{
			grades.push_back(grade);
			++scores[grade/10]; // 增加当前集群的计数器
		}
	}
	cout<<"grades.size = "< alt_score(11,0); // 11 个桶,最初都是 0
	// 对于输入中的每个等级
	for(auto it = grades.begin(); it != grades.end();++it)
	{
		unsigned i = *it;
		//增加当前集群的计数器
		++(*(alt_score.begin() + i/10));
	}

	cout<<"alt_scores.size = "<
#include 
#include 

using namespace std;
int main()
{
	vector text;// 保存输入
	string s;
	while(getline(cin,s)) // 读取整个输入文件
		text.push_back(s); // 将每一行存储为文本中的一个元素
	cout<<"text.size: "<empty(); ++it)
	{
		cout<<*it<
#include 
#include 
using namespace std;

int main()
{
	vector v = {0,1,2,3,4,5,6,7,8,9};
	auto sz = v.size();
	decltype(sz) i = 0;
	// 将 v 的内容复制到 v 的后面
	while(i != sz)
	{
		v.push_back(*v.begin() + i);
		++i;
	}
	//prints 0...9 0...9
	for(auto it:v)
		cout< alt_v = {0,1,2,3,4,5,6,7,8,9};
	// 值为 0...9 的向量
	for(decltype(alt_v.size())i = 0,sz = alt_v.size();i!=sz;++i)
	{
		alt_v.push_back(alt_v[i]);
	}
	// prints 0...9 0...9
	for(auto it : alt_v)
		cout< v2 = {0,1,2,3,4,5,6,7,8,9};// 值为 0 ... 9 的向量
	decltype(v2.size()) ix = 0;
	// 我们将使用 ix 来索引向量
	
	// 将值小于 5 的元素设置为 0
	while(ix != v2.size() && v2[ix] < 5)
	{
		v2[ix] = 0; // 改变v中元素的值
		++ix;// 增加索引,以便下一次迭代获取下一个元素
	}

	// 使用下标打印元素
	for(unsigned i = 0; i!=v2.size();++i)
		cout<alt_v2 = {0,1,2,3,4,5,6,7,8,9};// 值为 0...9 的向量
	// 将元素设置为 0,直到第一个 5 或更大的元素
	auto it = alt_v2.begin();
	while(it != alt_v2.end() && *it < 5)
	{
		*it = 0;// 改变 alt_v2 中元素的值
		++it; // 推进迭代器以表示下一个元素
	}
	for(auto it = alt_v2.begin();// 它表示 alt_v2 中的第一个元素
			it != alt_v2.end();// 只要它表示一个元素
			++it)// 将迭代器增加到下一个元素
		cout<<*it<<" ";// 从 alt_v2 打印由它表示的元素
	cout<
#include 
#include 

using namespace std;

int main()
{
	// 大小为 3 的数组; 每个元素都是一个包含 4 个未初始化整数的数组
	int ia1[3][4]; 
	// 大小为 10 的数组; 每个元素都是一个 20 元素的数组
	// 其元素是 30 个整数的数组
	// 将所有元素初始化为 0
	int arr[10][20][30] = {0};
	// 将 arr 的第一个元素分配给最后一个元素
	// 在 ia 的最后一行
	ia1[2][3] = arr[0][0][0];

	// 将行绑定到 ia 中的第二个四元素数组
	int (&row)[4] = ia1[1];

	// 三个元素,每个元素都是一个大小为4的数组
	int ia2[3][4] = {
		{0, 1, 2, 3},// 索引为 0 的行的初始值设定项
		{4, 5, 6, 7},// 索引为 1 的行的初始值设定项
		{8, 9, 10, 11}// 索引为 2 的行的初始值设定项
	};

	// 没有可选的等效初始化
	// 每行嵌套大括号
	int ia3[3][4] = {0,1,2,3,4,5,6,7,8,9,10,11};

	// 显式地只初始化每行中的元素 0
	int ia4[3][4] = {{ 0 }, { 4 }, { 8 }};
	
	// 显式初始化第 0 行; 其余元素
	// 是否已初始化值
	int ix[3][4] = {0,3,6,9};

	//prints 9 0 0 0
	cout<
using namespace std;

int main()
{
	cout<<-30 * 3 + 21 / 5<
#include 

using namespace std;

int ia[] = {1,2,3,3,4,5,6};

int main()
{
	constexpr size_t sz = sizeof(ia) / sizeof(*ia);
	int arr2[sz];
	cout<<"ia size: "<
#include 
#include 

using namespace std;

vector grades;

int main()
{
	unsigned i;
	while(cin>>i)
	{
		grades.push_back(i);
	}

	for(auto grade : grades) //对于成绩中的每个年级
	{
		// 将初始成绩设置为通过或失败
		string finalgrade = (grade < 60) ? "fail":"pass";

		finalgrade = (grade > 90) ? "high pass" : (grade < 60) ? "fail" : "pass";
		cout<
#include 
#include 
#include 

using namespace std;

string &tolower(string &s)
{
	for(auto &i : s)
	{
		i = tolower(i);
	}
	return s;
}

string &toupper(string &s)
{
	for(auto &i : s)
		i = toupper(i);
	return s;
}

int main()
{
	int i = 0;
	cout<

using namespace std;

int main()
{
	short short_value = 32767;// 如果shorts是16位的最大值
	short_value += 1; //这个计算溢出
	cout<<"short_value "<
using namespace std;

int main()
{
	Sales_data data, *p;
	sizeof(Sales_data); // 保存类型为 Sales_data 的对象所需的大小
	sizeof data; // 数据类型的大小,即 sizeof(Sales_data)
	sizeof p;// 指针大小
	sizeof *p; // p 指向的类型的大小,即 sizeof(Sales_data)
	sizeof data.revenue; // Sales_data 的收入成员类型的大小
	sizeof Sales_data::revenue; // 获取收入大小的另一种方法

	cout<<"short: "<
using namespace std;

int main()
{
	int i = 1024;
	int k = -i;
	bool b = true;
	bool b2 = -b;
	cout<
#include 
#include 
using namespace std;

int main()
{
	vector ivec; //空向量
	int cnt = 10;
	// 添加元素 10 . . . 1 到 ivec
	while(cnt > 0)
		ivec.push_back(cnt--); // int 后缀递减
	auto iter = ivec.begin();
	// 打印 10 9 8 。 . . 1
	while(iter != ivec.end())
		cout<<*iter++<<" "; // 迭代器后缀增量
	std::cout< vec2(10,0);// 十个元素最初都是 0
	cnt = vec2.size();
	// 从 size 分配值。 . . 1 到 vec2 中的元素
	for(vector::size_type ix = 0;
		ix != vec2.size(); ++ix,--cnt)
		vec2[ix] = cnt;

	iter = vec2.begin();
	// 打印 10 9 8 。 . . 1
	while(iter != vec2.end())
		cout<<*iter++<<" ";// 迭代器后缀增量
	std::cout<
using namespace std;

int main()
{
	// 编译器可能会警告精度损失
	int ival = 3.541 + 3;
	// 编译器可能会警告精度损失
	cout<
#include 
#include "Sales_item.h"
using namespace std;

int main()
{
	Sales_item item1,item2;
	while(cin>>item1>>item2)
	{
		try
		{
			// 执行将添加两个 Sales_items 的代码
			// 如果添加失败,代码抛出runtime_error异常
			// 首先检查数据是否为同一个项目
			if(item1.isbn() != item2.isbn())
				throw runtime_error("数据必须引用相同的 ISBN");

			// 如果我们还在这里,ISBN 是一样的
			cout<>c;
			if(!cin || c == 'n')
				break;// 跳出while循环
		}// 结束 catch 子句
	}// 结束while循环
	return 0;//表示成功
}

#include 
#include 
using namespace std;

int main()
{
	// 反复询问用户要求和的一对数字
	string rsp;// 用于条件; 不能在 do 中定义
	do
	{
		cout<<"请输入两个值:";
		int val1 = 0,val2 = 0;
		cin>>val1>>val2;
		cout<<"总数是 "<>rsp;
	}while(!rsp.empty() && rsp[0] != 'n');

	cout<
#include 
#include 

using namespace std;

const vector scores = {"F", "D", "C", "B", "A", "A++"};
vector grades;

// 这些函数演示了处理 if 测试的替代方法
// 接受一个无符号值和一个字符串的函数
// 并返回一个字符串
string goodVers(string lettergrade, unsigned grade)
{
	// 为以 8 或 9 结尾的成绩添加加号,为以 0、1 或 2 结尾的成绩添加减号
	if(grade % 10 > 7)
		lettergrade += '+';	// 以 8 或 9 结尾的成绩得到一个“+”
	else
		if(grade % 10 < 3)
			lettergrade += '-'; // 以 0、1 或 2 结尾的得到一个“-”
	return lettergrade;
}

// 为成绩添加加号或减号的函数版本不正确
string badVers(string lettergrade,unsigned grade)
{
	// 为以 8 或 9 结尾的成绩添加加号,为以 0、1 或 2 结尾的成绩添加减号
	// 错误:执行与缩进不匹配; else 与内部 if 一致
	if(grade % 10 >= 3)
		if(grade % 10 > 7)
			lettergrade += '+';// 以 8 或 9 结尾的成绩获得 +
	else
		lettergrade += '-';// grades ending in 3, 4, 5, 6 will get a minus!

	return lettergrade;
}

// 使用与 badVers 相同的逻辑路径修正版本
string rightVers(string lettergrade, unsigned grade)
{
	// 为以 8 或 9 结尾的成绩添加加号,为以 0、1 或 2 结尾的成绩添加减号
	if(grade % 10 >= 3)
	{
		if(grade % 10 > 7)
			lettergrade += '+'; // 以 8 或 9 结尾的成绩获得 +
	}
	else
		lettergrade += '-';// 以 0、1 或 2 结尾的成绩将减分
	return lettergrade;
}

int main()
{
	// 从输入中读取一组分数
	unsigned grade;
	while(cin>>grade)
		grades.push_back(grade);

	// 现在处理这些成绩
	for(auto it : grades)
	{
		// 对于我们阅读的每个年级
		cout< 59 && it != 100)
		{
			cout<<"替代版本:"<
using namespace std;

int main()
{
	char ch;
	// 为每个元音初始化计数器
	unsigned vowelCnt = 0;
	unsigned otherCnt = 0;
	// 计算任何不是元音的东西

	while(cin >> ch)
	{
		// 如果 ch 是元音,则增加相应的计数器
		switch(ch)
		{
			case 'a': case 'e': case 'i': case 'o': case 'u':
				++vowelCnt;
				break;
			default:
				++otherCnt;
				break;
		}
	}
	//打印结果
    cout << "元音数: t" << vowelCnt << 'n'
         << "非元音总数: t" << otherCnt << 'n';
    return 0;
}

#include 
#include 
#include 

using namespace std;

int main()
{
	vector ivec;
	vector v = {0,1,2,3,4,5,6,7,8,9};

	// 范围变量必须是一个引用,以便我们可以写入元素
	for(auto &r : v) // 对于 v 中的每个元素
		r *= 2; // 将 v 中每个元素的值加倍

	// 打印 v 中的每个元素
	for(int r : v)
		cout<

using namespace std;
int main()
{
	unsigned aCnt = 0,eCnt = 0,iCnt = 0,oCnt = 0,uCnt = 0;
	char ch;
	while(cin >> ch)
	{
		//如果 ch 是元音,则增加适当的计数器
		switch(ch)
		{
			case 'a':
				++aCnt;
				break;
			case 'e':
				++eCnt;
				break;
			case 'i':
				++iCnt;
				break;
			case 'o':
				++oCnt;
				break;
			case 'u':
				++uCnt;
				break;
		}
	}
	//打印结果
    cout << "元音数 a: t" << aCnt << 'n'
         << "元音数 e: t" << eCnt << 'n'
         << "元音数 i: t" << iCnt << 'n'
         << "元音数 o: t" << oCnt << 'n'
         << "元音数 u: t" << uCnt << endl;
}

xz@xiaqiu:~/study/cpp-primer/study/build$ ./test 
ewqewqretgrfsadxzxczvcxvcxzdsadfsfdffedfrrgtrjyjukiuihnhggfbfdvdfw
元音数 a: 	2
元音数 e: 	4
元音数 i: 	2
元音数 o: 	0
元音数 u: 	2
xz@xiaqiu:~/study/cpp-primer/study/build$ 

#include 
#include 
using namespace std;

#define  DSADSA 

// 用于说明数组相关类型声明的代码
int arr[10]; // arr 是一个包含十个整数的数组
int *p1[10]; // p1 是一个包含十个指针的数组
int (*p2)[10] = &arr; // p2 指向一个包含十个整数的数组

using arrT = int[10];// arrT 是十个整数类型数组的同义词

// 声明函数的三种方法,返回指向十个整数数组的指针
arrT* func(int i);// 使用类型别名
auto func(int i)->int(*)[10]; // 使用尾随返回类型
int (*func(int i))[10]; // 直接声明

auto func2(int i)->int(&)[10]; // func2 返回对数组的引用

// 两个数组
int odd[] = {1,3,5,7,9};
int even[] = {0,2,4,6,8};

// 返回指向这些数组之一中的 int 的指针的函数
int *elemPtr(int i)
{
	// 返回一个指向这些数组中第一个元素的指针
	return (i % 2) ? odd : even;
}

// 返回一个指向包含五个 int 元素的数组的指针
decltype(odd) *arrPtr(int i)
{
	return (i % 2) ? &odd : &even;// 返回一个指向数组的指针
}

// 返回对包含五个 int 元素的数组的引用
int (&arrRef(int i))[5]
{
	return (i % 2) ? odd : even;
}

int main()
{
	int *p = elemPtr(6);// p 指向一个 int
	int (*arrP)[5] = arrPtr(5); // aarP 指向一个包含五个整数的数组
	int (&arrR)[5] = arrRef(4); // arrR 指的是一个包含五个整数的数组

	for(size_t i = 0; i < 5; ++i)
	{
		// p 指向数组中的一个元素,我们下标
		cout<
using namespace std;

size_t count_calls()
{
	static size_t ctr = 0;// 值将在调用之间保持不变
	return ++ctr;
}
int main()
{
	for(size_t i = 0; i != 10; ++i)
		cout<
#include 
#include 
#include 
#include 
using namespace std;

struct ErrCode
{
	ErrCode(int i) : num(i){}// 初始化 ErrCode 类型的对象
	string msg() // ErrCode 的成员函数
	{
		ostringstream s;
		s<<"ErrCode "< il)
{
	for(auto beg = il.begin(); beg != il.end(); ++beg)
		cout<<*beg<<" ";
	cout< il)
{
	cout< functionX()
{
	string expected = "description",
	actual = "some other case";
	//...
	if(expected.empty())
		return {};// 返回一个空向量
	else if(expected == actual)
		return {"functionX","okay"};// 返回列表初始化的向量
	else
		return {"functionX",expected,actual};
}

int main()
{
	string expected = "description",actual = "some other case";
	initializer_list li = {0,1,2,3};

	// 预期,实际是字符串
	if(expected != actual)
		error_msg({"functionX",expected,actual});
	else
		error_msg({"functionX","okay"});

	// 预期,实际是字符串
	if(expected != actual)
		error_msg(ErrCode(42),{"functionX",expected,actual});
	else
		error_msg(ErrCode(0),{"functionX","okay"});
	// 可以传递一个空列表,调用第二个版本的 error_msg
	error_msg({});// 打印空行
	// 调用列表初始化其返回值的函数
	// 结果是一个向量
	auto result = functionX();
	for(auto i : result)
		cout<
int main()
{
	cout<
#include 
using namespace std;

// 声明(严格来说在这个文件中不是必需的)
string::size_type sumLength(const string&, const string&);
string::size_type largerLength(const string&, const string&);

// 定义这些函数
string::size_type sumLength(const string& s1,const string &s2)
{
	return s1.size() + s2.size();
}

string::size_type largerLength(const string &s1, const string &s2)
{
	return (s1.size() > s2.size()) ? s1.size() : s2.size();
}

// 根据其字符串参数的值,
// getFcn 返回指向 sumLength 或 largeLength 的指针
// 三种方式声明getFcn
// 1. 使用 decltype 作为返回类型,
// 记得加一个*表示getFcn返回一个指针
decltype(sumLength) *getFcn(const string&);
// 使用尾随返回类型
auto getFcn(const string&) -> string::size_type(*)(const string&, const string&);
// 直接定义
string::size_type (*getFcn(const string &))(const string&, const string&);

// 定义 getFcn
decltype(sumLength)*
getFcn(const string& fetch)
{
	if(fetch == "sum")
		return sumLength;
	return largerLength;
}
int main()
{
	// "sum" 是 getFcn 的参数
	// ("hello", "world!") 是函数 getFcn 返回的参数
	cout<
#include 
#include 

using namespace std;
// const int ia[] 等价于 const int* ia
// 显式传递大小并用于控制对 ia 元素的访问
void print(const int ia[], size_t size)
{
	for(size_t i = 0; i != size; ++i)
	{
		cout<
#include 
using namespace std;

inline const string &
shorterString(const string& s1, const string &s2)
{
	return s1.size() <= s2.size() ? s1 : s2;
}

int main()
{
	string s1("successes"),s2("failure");
	cout<
int main()
{
	bool some_failure = false;
	if(some_failure)
		return EXIT_FAILURE; 
	else
		return EXIT_SUCCESS; //在 cstdlib 中定义
}


#include 
#include 
using namespace std;

int main()
{
  short i = 65537; 
  int j = i + 1;  
  cout<(65537)<(65538)<shortSet;
  shortSet.set();
  cout<

class A
{
public:
	void test(){printf("test Anthis = %dn",this);}
};

int main()
{
	A *pA = NULL;
	pA->test();
	return 0;
}





//静态绑定
//this == 0



xz@xiaqiu:~/study/cpp-primer/study/1$ ./2
test A
this = 0
xz@xiaqiu:~/study/cpp-primer/study/1$ 





#include 
#include 
#include 
using namespace std;
string getClearName(const char* name)
{
  int status = -1;
  char* clearName = abi::__cxa_demangle(name,NULL,NULL,&status);
  const char* const demangledName = (status == 0)?clearName : name;
  string ret_val(demangledName);
  free(clearName);
  return ret_val;
}

int main()
{
    int a[2][2][3] = {{{1,2,3},{4,5,6}},{{7,8,9},{10,11,12}}};
    int *ptr = (int*)(&a+1);
    printf("%d %dn", *(int*)(a + 1), *(ptr - 1));
    cout<
#include 
#include 

using namespace std;
string getClearName(const char* name)
{
  int status = -1;
  char* clearName = abi::__cxa_demangle(name,NULL,NULL,&status);
  const char* const demangledName = (status == 0)?clearName : name;
  string ret_val(demangledName);
  free(clearName);
  return ret_val;
}

int main()
{
  static char* s[] = {"black","white","pink","violet"};
  char **ptr[] = {s+3,s+2,s+1,s}, ***p;
  p = ptr;++p;
  printf("%sn",*(s));
  printf("%sn",*(s+1)); 
  printf("%sn",*(s+2)); 
  printf("%sn",*(s+3));
  printf("%sn",(**p)+1); 

  cout<<"------------------------"<"black"
|s[1]|--------->"white"
|s[2]|--------->"pink"
|s[3]|--------->"violet"
--------------------------------------------
s 	= s[0]
s+1 = s[1]
s+2 = s[2]
s+3 = s[3]

char **ptr[] = {s+3,s+2,s+1,s};

|ptr[0]|------->|s[3]|--------->"violet"
|ptr[1]|------->|s[2]|--------->"pink"
|ptr[2]|------->|s[1]|--------->"white"
|ptr[3]|------->|s[0]|--------->"black"

***p
p = ptr; 

p------->|ptr[0]|------->|s[3]|--------->"violet"
		 |ptr[1]|------->|s[2]|--------->"pink"
		 |ptr[2]|------->|s[1]|--------->"white"
		 |ptr[3]|------->|s[0]|--------->"black"
++p;
		 |ptr[0]|------->|s[3]|--------->"violet"
p------->|ptr[1]|------->|s[2]|--------->"pink"
		 |ptr[2]|------->|s[1]|--------->"white"
		 |ptr[3]|------->|s[0]|--------->"black"

(**p)+1
		 |ptr[0]|------->|s[3]|--------->"violet"
		 |ptr[1]|------->|s[2]|--------->"pink"<----------(**p)
		 |ptr[2]|------->|s[1]|--------->"white"
		 |ptr[3]|------->|s[0]|--------->"black"

(**p)+1------------------->"ink"






#include 
using namespace std;
class animal
{
protected:
	int age;
public:
	virtual void print_age(void) = 0;
	virtual void print_age1(void) = 0;

};

class dog:public animal
{
public:
	dog(){this->age = 2;}
	~dog(){}
	virtual void print_age(void)
	{
		cout<<"wang.my age = "<age<print_age();
	pa->print_age1();

	system("pause");
	return 0;
}





xz@xiaqiu:~/study/cpp-primer/study/1$ ./5 
2c44dce8
2c44dce8
2c44dce8
-----------------
2c44dcc8
2c44dcc8
2c44dcc8
wang.my age = 1
wang.my age1 = 1
sh: 1: pause: not found
xz@xiaqiu:~/study/cpp-primer/study/1$ 





#include 

using namespace std;
int i = 0;
int fun(int n)
{
	static int a = 2;
	a++;
	return (a * n);
}
int main()
{
	int k = 5;
	{
		int i = 2;
		k += fun(i); //2 x 3 + 5 = 11
		cout<
using namespace std;
class B
{
public:
	B(){cout<<"default constructor"<
#include 

class CBuffer
{
	char *m_pBuffer;
	int m_size;
public:
	CBuffer(){ m_pBuffer = NULL;}
	~CBuffer(){ Free(); }
	void Allocte(int size) { 
		m_size = size; 
		m_pBuffer = new char[size];
	}
private:
	void Free()
	{
		if(m_pBuffer != NULL)
		{
			delete[] m_pBuffer;
			m_pBuffer = NULL;
		}
	}
public:
	void SaveString(const char* pText)
	{
		Allocte(sizeof(pText));
		strcpy(m_pBuffer,pText);
	}
	char *GetBuffer() const
	{
		return m_pBuffer;
	}
};

int main()
{
	CBuffer buffer1;
	buffer1.SaveString("Microsoft");
	printf("%sn", buffer1.GetBuffer());
}





xz@xiaqiu:~/study/cpp-primer/study/1$ ./8
Microsoft
xz@xiaqiu:~/study/cpp-primer/study/1$ 



#include 
#include 
#include 

using namespace std;

inline string make_plural(size_t ctr, const string& word,
							   const string& ending)
{
	return (ctr > 1) ? word + ending : word;
}

int main()
{
	size_t cnt = 1;
	cout<
#include 

char &get_val(string &str, string::size_type ix)
{
	return str[ix];
}

int main()
{
	string s("a value");
	cout<
#include 
#include 
#include 

// 返回 c 在 s 中第一次出现的索引
// 引用参数出现计算 c 出现的频率
string::size_type find_char(const string& s,char c,string::size_type &occurs)
{
	auto ret = s.size(); // 第一次出现的位置,
	occurs = 0; //如果有的话设置出现次数参数	

	for(decltype(ret) i = 0; i != s.size(); ++i)
	{
		if(s[i] == c)
		{
			if(ret == s.size())
				ret = i; // 记住第一次出现 c 
			++occurs; //增加出现次数
			
		}
	}
	return ret;// 计数在发生时隐式返回
}
// 返回一个引用第一次出现的值的迭代器
// 引用参数出现包含第二个返回值
vector::const_iterator	find_char(
	vector::const_iterator beg,// 第一个元素
	vector::const_iterator end, // 最后一个元素
	int value,// 我们想要的值
	vector::size_type &occurs // 出现的次数
	)
{
	auto res_iter = end;// res_iter 将保存第一次出现,如果有的话
	occurs = 0; // 设置出现次数参数

	for(;beg != end;++beg)
	{
		if(*beg == value)
		{
			// 记住第一次出现的值
			if(res_iter == end)
				res_iter = beg;
			++occurs;// 增加出现次数
		}
	}
	return res_iter; // 在发生时隐式返回的计数
}

int main()
{
	string s;
	getline(cin,s);
	size_t ctr = 0;
	auto index = find_char(s,'o',ctr);
	cout< ivec;
	int i;
	// 在发生时隐式返回的计数
	while(cin >> i)
		ivec.push_back(i);

	// 对于整数列表中的每个值
	for(auto i : {42,33,92})
	{
		auto it = find_char(ivec.begin(),ivec.end(),i,ctr);
		if(it == ivec.end())
			cout<
// get 返回对给定数组中元素的引用
int &get(int *arry, int index){ return arry[index]; }

int main()
{
	int ia[10]; // 十个未初始化整数的数组
	for(int i = 0; i != 10; ++i)
	{
		get(ia,i) = i;// 调用 get 为元素赋值
	}

	for(auto i : ia) // 打印元素
		cout<
#include 

using namespace std;
// 引用 int 的函数
// 并将给定的对象设置为零
// i 只是传递给 reset 的对象的另一个名称
void reset(int &i)
{
	i = 0;// 改变 i 所指对象的值
}

// 带指针的函数
// 并将指向的值设置为零
void reset(int *ip)
{
	*ip = 0; // 改变ip指向的对象的值
	ip = 0;// 改变ip的本地副本; 参数不变
}

int main()
{
	int j = 42;
	reset(j); // j 通过引用传递; j 中的值发生了变化
	cout<<"j = "<
#include 

using namespace std;

// 返回整数向量中最小元素的函数
int min_element(vector::iterator,
				vector::iterator);
// 指向函数的指针,初始化为指向 min_element

int (*pf)(vector::iterator,vector::iterator) = min_element;

int main()
{
	vector ivec{1,3,4,5,-1,32,-32};
	// 给 ivec 一些值
	cout<<"直接调用:"
		<::iterator beg,
				vector::iterator end)
{
	int minVal = 0;
	while(beg != end)
	{
		if(minVal > *beg)
			minVal = *beg;
		++beg;
	}	
	return minVal;
}

xz@xiaqiu:~/study/cpp-primer/study/build$ ./test 
直接调用:-32
间接调用:-32
等效的间接调用:-32
xz@xiaqiu:~/study/cpp-primer/study/build$ 

#include 
#include 
#include 
#include 
using namespace std;

void print(const int ia[], size_t size)
{
#ifndef NDEBUG
// __func__ 是一个由编译器定义的局部静态变量,它保存着这个函数的名字
cerr<<__func__<<" : 数组大小是 "< threshold);
	return 0;
}

xz@xiaqiu:~/study/cpp-primer/study/build$ ./test 
错误: /home/xz/study/cpp-primer/study/main1.cpp : 在函数中 main 在行 3264
 at 21:24:24
字读为 "foo": 长度太短
xz@xiaqiu:~/study/cpp-primer/study/build$ 

#include 
class Account
{
public:
	Account() = default;
	Account(const std::string &s,double amt):
		owner(s),amount(amt){}
	void calculate() { amount += amount * interestRate;}
	double balance() { return amount; }
public:
	static double rate() { return interestRate; }
	static void rate(double);
private:
	std::string owner;
	double amount = 0.0;
	static double interestRate;
	static double initRate() { return .0225; }
	static const std::string accountType;
	static constexpr int period = 30;// period 是一个常量表达式
	double daily_tbl[period];
};

// 定义静态数据和函数成员
const string Account::accountType("Saving Account");
double Account::interestRate = initRate();

void Account::rate(double newRate)
{
	interestRate = newRate;
}


#include 
using namespace std;

int main()
{
	Sales_data data1,data2;
	if(read(cin,data1) && read(cin,data2))
	{
		if(data1.isbn() == data2.isbn())// 读取交易
		{
			data1.combine(data2);// 添加交易
			print(cout,data1);// 打印结果
			cout<
using namespace std;

int main()
{
	Sales_data total; // 保存运行总和的变量
	if(read(cin, total)) // 读取第一笔交易
	{
		Sales_data trans;// 保存下一个交易数据的变量
		// 交易包含 ISBN、售出的副本数量和销售价格
		while(read(cin,trans)) // 读取剩余的交易
		{
			if(total.isbn() == trans.isbn()) // 检查isbn
			{
				total.combine(trans);// 更新运行总数
			}
			else
			{
				print(cout,total)<
using namespace std;

int main()
{
	constexpr Debug io_sub(false,true,false);//调试IO
	if(io_sub.any()) // 等价于 if(true)
		cerr<<"打印适当的错误信息"<
#include 

class Screen
{
public:
	typedef std::string::size_type pos;
	Screen() = default; // 需要,因为 Screen 有另一个构造函数
	//cursor被它的类内初始化器初始化为 0
	Screen(pos ht,pos wd, char c): height(ht),width(wd),contents(ht * wd,c){}
	friend class Window_mgr;
	Screen(pos ht = 0,pos wd = 0):
		cursor(0),height(ht),width(wd),contents(ht * wd, ' '){}
	char get() const // 获取光标处的字符
	{
		return contents[cursor]; // 隐式内联
	}
	inline char get(pos ht, pos wd) const; // 显式内联
	Screen &clear(char = bkground);
private:
	static const char bkground = ' ';
public:
	Screen &move(pos r, pos c); // 可以稍后内联
	Screen &set(char);
	Screen &set(pos,pos,char);
	// 显示重载对象是否为常量
	Screen &display(std::ostream &os)
	{
		do_display(os);
		return *this;
	}
	const Screen &display(std::ostream &os) const
	{
		do_display(os);
		return *this;
	}
private:
	// 完成显示屏幕工作的函数
	void do_display(std::ostream &os) const { os << contents; }
	pos cursor = 0;
	pos height = 0,width = 0;
	std::string contents;
};

Screen &Screen::clear(char c)
{
	contents = std::string(height * width,c);
	return *this;
}

inline // 我们可以在定义中指定内联
Screen &Screen::move(pos r, pos c)
{
	pos row = r * width; // 计算行位置
	cursor = row + c; // 将光标移动到该行内的列
	return *this; // 将此对象作为左值返回
}

char Screen::get(pos r, pos c) const // 在类中声明为内联
{
	pos row = r * width;// 计算行位置
	return contents[row + c]; // 返回给定列的字符
}

inline Screen &Screen::set(char c)
{
	contents[cursor] = c;// 在当前光标位置设置新值
	return *this;// 将此对象作为左值返回
}

inline Screen &Screen::set(pos r, pos col, char ch)
{
	contents[r*width + col] = ch;// 将指定位置设置为给定值
	return *this; // 将此对象作为左值返回
}

#include 
#include 
using namespace std;
int main()
{
	Screen myScreen(5,3);
	// 将光标移动到给定位置,并设置该字符
	myScreen.move(4,0).set('#');

	Screen nextScreen(5,5,'X');
	nextScreen.move(4,0).set('#').display(cout);
	cout<<"n";
	nextScreen.display(cout);
	cout<
using namespace std;
int main()
{
	// 写入 hi 和换行符,然后刷新缓冲区
	cout<<"hi!"<
#include 
#include 
using namespace std;

void read()
{
	// 打开fail和bad位
	cin.setstate(cin.badbit | cin.eofbit | cin.failbit);
}

void off()
{
	// 关闭 failbit 和 badbit 但所有其他位不变
	cin.clear(cin.rdstate() & ~cin.failbit & ~cin.badbit);
}

int main()
{
	cout<<"before read"<
#include 
#include 
#include 

using namespace std;

void process(ifstream &is)
{
	string s;
	while(is >> s)
		cout<
#include 
#include 
#include 

using namespace std;
// 成员默认是公开的
struct PersonInfo
{
	string name;
	vector phones;
};

// 我们将在第 17 章中看到如何重新格式化电话号码
// 现在只返回给定的字符串
string format(const string &s){ return s;}

bool valid(const string &s)
{
	// 我们将看到如何验证电话号码
	// 在第 17 章中,现在只返回 true
	return true;
}

vector getData(istream &is)
{
	//将分别保存输入中的一行和单词
	string line,word;

	// 将保存输入中的所有记录
	vector people;

	// 一次读取输入一行,直到文件结束(或其他错误)
	while(getline(is,line))
	{
		PersonInfo info;// 保存这条记录数据的对象
		istringstream record(line); // 将记录绑定到我们刚刚读取的行
		record >> info.name;//读取名字
		while(record >> word)//读取电话号码
			info.phones.push_back(word); // 并存储它们
		people.push_back(info); // 将此记录附加到人
	}
	return people;
}

ostream& process(ostream &os,vectorpeople)
{
	for(const auto &entry : people) // 对于 people 中的每个条目
	{
		ostringstream formatted,badNums; // 在每个循环上创建的对象
		for(const auto &nums : entry.phones) // 对于每个number
		{
			if(!valid(nums))
			{
				badNums<<" "<
#include 
using namespace std;

int main()
{
	vector ivec;
	// 大小应该为零; 容量是实现定义的
	cout<<"ivec: size: "<::size_type ix = 0; ix != 24;++ix)
		ivec.push_back(ix);

	// 大小应该是 24; 容量将 >= 24 并且是实现定义的
	cout<<"ivec: size: "<= 50 并且是实现定义的
	cout<<"ivec: size: "<= 51 并且是实现定义的
	cout<<"ivec: size: "<
#include 
#include 
#include 
using namespace std;

int main()
{
	list slist;
	string s;
	while(cin >> s)
		slist.push_back(s);// 将内容读入slist
	
	auto iter = std::find(slist.begin(),slist.end(),"Quasimodo");
	if(iter != slist.end())
		slist.erase(iter);

	auto orig = slist; // 在销毁内容之前保留一份副本
	slist.clear();// 删除容器内的所有元素
	cout<<"after clear,size is: "<
#include 
#include 
#include 
#include 

using namespace std;

int main()
{
	// 在调用 elem1 == elem2 之后
	list lst = {0,1,2,3,4,5,6,7,8,9};

	// 打印 lst 中的初始值
	cout<<"initial list: ";
	for(auto it : lst)
		cout< flst = {0,1,2,3,4,5,6,7,8,9};

	// 在平面上打印初始值
	cout<<"initial list:";
	for(auto it : flst)
		cout<
#include 
using namespace std;

int main()
{
	string name("AnnaBelle");
	auto pos1 = name.find("Anna"); // pos1 == 0
	cout<
#include 
using namespace std;

void printVec(const vector &vi)
{
	// 打印向量的元素
	auto iter = vi.begin();
	while(iter != vi.end())
		cout<<*iter++<<" ";
	cout< vi = {0,1,2,3,4,5,6,7,8,9};
	printVec(vi);

	// 我们调用begin,而不是cbegin,因为我们正在改变vi
	auto iter = vi.begin();
	while(iter != vi.end())
	{
		if(*iter % 2)// 如果元素是奇数
		{
			iter = vi.insert(iter,*iter); // 复制它
			iter += 2;// 跳过这个元素和新元素
		}
		else
			iter = vi.erase(iter); // 删除偶数元素
		// 不要推进迭代器;
		// iter 表示我们擦除后的元素
	}
	printVec(vi);
	return 0;
}
xz@xiaqiu:~/study/cpp-primer/study/build$ ./test 
0 1 2 3 4 5 6 7 8 9 
1 1 3 3 5 5 7 7 9 9 
xz@xiaqiu:~/study/cpp-primer/study/build$ 

#include 
#include 
#include 
#include 
using namespace std;

bool process(int);

int main()
{
	stack intStack; // 空栈
	// 填满栈
	for(size_t ix = 0; ix != 10; ++ix)
		intStack.push(ix);
	// intStack 持有 0 。 . . 9 包含
	// 当 intStack 中还有值时
	while(!intStack.empty())
	{
		int value = intStack.top();
		// 使用值的代码
		cout<
#include 
#include 
using namespace std;

int main()
{
	string s = "some string",s2	= "some other string";
	// 在 s 开头插入 s2 中所有字符的等效方法
	// 在 s.begin() 之前插入迭代器范围
	s.insert(s.begin(),s2.begin(),s2.end());
	cout<<"insert iterators version: "< c_vec(1,'a');
	// 将 c_vec 中的字符插入到 s
	s.insert(s.begin(),c_vec.begin(),c_vec.end());
	s.insert(s.size(),5,'!');// 在 s 末尾添加五个感叹号
	cout<
#include 
#include 

using namespace std;
int main()
{
	try
	{
		string s("hello world");
		cout<
#include 
#include 
#include 
using namespace std;

int main()
{
	vector vi;
	int i;
	while(cin>>i)
		vi.push_back(i);
	// 将 lambda 传递给 for_each 以打印 vi 中的每个元素
	for_each(vi.begin(),vi.end(),[](int i){ cout< orig = vi; // 在vi中保存原始数据

	//用它们的绝对值替换负值
	std::transform(vi.begin(),vi.end(),vi.begin(),[](int i){return i < 0?-i:i;});
	// 现在在 vi 中打印元素
	for_each(vi.begin(),vi.end(),[](int i){cout<int{
		if(i<0) return -i;else return i;
	});
	// 现在在 vi 中打印元素
	for_each(vi.begin(),vi.end(),[](int i){cout<
#include 
#include 
#include 
#include 
#include 

using namespace std;

int main()
{
	vector vec(10); // 默认初始化为 0
	fill(vec.begin(),vec.end(),1);// 将每个元素重置为 1

	// 对 vec 中的元素求和,从值 0 开始求和
	int sum = accumulate(vec.begin(),vec.end(),0);
	cout<>s)
		v.push_back(s);
	string concat = accumulate(v.cbegin(),v.cend(),string(" "));
	cout<
#include 
#include 
using namespace std;

int main()
{
	istream_iterator in(cin),eof;
	cout<
#include 
using namespace std;

int main(int argc, char const *argv[])
{
	// 可以读写Sales_items的迭代器
	istream_iterator item_iter(cin),eof;
	ostream_iterator out_iter(cout,"n");

	// 将第一笔交易存入 sum 并读取下一条记录
	Sales_item sum = *item_iter++;

	while(item_iter != eof)
	{
		// 如果当前交易(在 item_iter 中)
		//有相同的 ISBN
		if(item_iter->isbn() == sum.isbn())
			sum += *item_iter++; // 将其添加到总和
								 // 并读取下一个事务
		else
		{
			out_iter = sum; // 写入当前和
			sum = *item_iter++;// 读取下一个交易
		}
	}
	out_iter = sum; // 记得打印最后一组记录
	return 0;
}

xz@xiaqiu:~/study/cpp-primer/study/build$ ./test 
111 12 12
111 1  12
111 23 12
112 12 1
111 36 432 12
112 23 2
112 23 4
113 12 3
112 58 150 2.58621
113 12 36 3
xz@xiaqiu:~/study/cpp-primer/study/build$ 

#include 
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
using namespace std::placeholders;
ostream &print(ostream &os, const string &s, char c)
{
	return os< words;
	while(cin>>s)
		words.push_back(s);
	std::for_each(words.begin(),words.end(),
		std::bind(print,ref(cout),placeholders::_1,' '));
	cout< in(is),eof;
	for_each(in,eof,bind(print,ref(cout),_1,'n'));
	cout<
#include 
#include 
#include 
using namespace std;

// 用于按字长排序的比较函数
bool isShorter(const string &s1, const string &s2)
{
	return s1.size() < s2.size();
}

bool LT(const string &s1, const string &s2)
{
	return s1 < s2;
}

void print(const vector &words)
{
	for_each(words.begin(),words.end(),
		[](const string &s){cout< words;
	// 将每本书的内容复制到一个向量中
	string next_word;
	while(cin >> next_word)
	{
		// 在词尾插入下一本书的内容
		words.push_back(next_word);
	}
	print(words);
	vector cpy = words;
	// 保存原始数据
	// 使用字符串 < 比较元素 
	// 排序并打印向量
	sort(words.begin(), words.end());

	words = cpy; // 返回原始数据
	// 使用 LT 函数比较元素
	// 应该与前一个排序有相同的输出
	sort(words.begin(),words.end(),LT);
	print(words);

	words = cpy; // 返回原始数据

	// 消除重复
	sort(words.begin(),words.end());
	auto it = unique(words.begin(),words.end());
	words.erase(it,words.end());

	// 使用函数按长度排序
	stable_sort(words.begin(),words.end(),isShorter);
	print(words);

	words = cpy;// 返回原始数据
	// 按字长对原始输入进行排序,从最短到最长
	sort(words.begin(),words.end(),isShorter);
	print(words);

	// 使用 bind 反转 isShorter 将最长到最短排序
	sort(words.begin(),words.end(),bind(isShorter,placeholders::_2,placeholders::_1));
	print(words);

	return 0;
}

xz@xiaqiu:~/study/cpp-primer/study/build$ ./test 
hello world make equal missing ping test shell test
hello world make equal missing ping test shell test 
equal hello make missing ping shell test test world 
make ping test equal hello shell world missing 
make ping test test hello world equal shell missing 
missing hello world equal shell make ping test test 
xz@xiaqiu:~/study/cpp-primer/study/build$ 


#include 
#include 
#include 
#include 
#include 
using namespace std;

int main()
{
	list roster1;
	vector roster2;
	roster2 = {"hello", "so long", "tata"};
	roster1 = {"hello", "so long"};

	// roster2 应该至少有与 roster1 一样多的元素
	auto b = 
		equal(roster1.cbegin(),roster1.cend(),roster2.cbegin());

	(b)?cout<<"true" : cout<<"false";
	cout<
#include 
#include 
using namespace std;

int main()
{
	// 使用 istream_iterator 来初始化一个向量
	istream_iterator in_iter(cin),eof;
	vector vec(in_iter,eof);

	for(auto it : vec)
		cout<
#include 
#include 
#include 
#include 

using namespace std;

void print(const string &label, const list& lst)
{
	cout< lst = {1,2,3,4};
	print("lst",lst);

	// 复制完成后,lst2 包含 4 3 2 1
	list lst2,lst3; // 空列表
	copy(lst.cbegin(),lst.cend(),front_inserter(lst2));

	// 复制完成后,lst3 包含 1 2 3 4
	copy(lst.cbegin(),lst.cend(),inserter(lst3,lst3.begin()));

	print("lst2",lst2);
	print("lst3",lst3);

	vector v = {1,2,3,4,5};
	list new_lst = {6,7,8,9};
	auto it = new_lst.begin();
	copy(v.begin(),v.end(),inserter(new_lst,it));
	print("new_lst",new_lst);

	return 0;
}

xz@xiaqiu:~/study/cpp-primer/study/build$ ./test 
lst
1 2 3 4 
lst2
4 3 2 1 
lst3
1 2 3 4 
new_lst
1 2 3 4 5 6 7 8 9 
xz@xiaqiu:~/study/cpp-primer/study/build$ 


#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

int main()
{
	istream_iterator int_it(cin);// 从cin读取整数
	istream_iterator int_eof;// 结束迭代器值
	vector v(int_it,int_eof);// 通过读取cin初始化v

	sort(v.begin(),v.end());
	ostream_iterator out(cout," ");// 将整数写入 cout
	unique_copy(v.begin(),v.end(),out);// 将唯一元素写入 cout
	cout<out_iter(out_file," ");
	copy(v.begin(),v.end(),out_iter);
	out_file<
#include 
#include 

using namespace std;

// 五个函数说明了 lambda 表达式的不同方面
void fcn1()
{
	size_t v1 = 42; // 局部变量
	// 将 v1 复制到名为 f 的可调用对象中
	auto f = [v1] { return v1; };
	v1 = 0;
	auto j = f();// j 是 42; f 在创建 v1 时存储了它的副本
	cout<
#include 
#include 
#include  //size_t
#include 
#include 

using namespace std::placeholders;

// 用于按字长排序的比较函数
bool isShorter(const string &s1, const string &s2)
{
	return s1.size() < s2.size();
}

// 判断给定单词的长度是否为 6 或更多
bool GT(const string &s, string::size_type m)
{
	return s.size() >= m;
}

void elimDups(vector &words)
{
	// 按字母顺序对单词进行排序,以便我们可以找到重复项
	sort(words.begin(),words.end());
	for_each(words.begin(),words.end(),
		[](const string &s){ cout< &words,vector::size_type sz)
{
	elimDups(words);
	// 按字母顺序排列单词并删除重复项
	// 按大小排序单词,但对相同大小的单词保持字母顺序
	stable_sort(words.begin(),words.end(),
		[](const string &a, const string &b){
			return a.size() < b.size();
		});
	// 获取第一个元素的迭代器,其 size() 为 >= sz
	auto wc = find_if(words.begin(), words.end(),
		[sz](const string &a){
			return a.size() >= sz;
		});
	// 计算大小 >= sz 的元素数量
	auto count = words.end() - wc;
	cout<= sz;
}

int main()
{
	vector words;
	// 将每本书的内容复制到一个向量中
	string next_word;
	while(cin >> next_word)
	{
		// 在词尾插入下一本书的内容
		words.push_back(next_word);
	}

	biggies(words,5);// biggies 改变它的第一个参数
	// 使用 bind 和 check_size 函数的替代解决方案
	// 注意:单词在 biggies 中被更改,
	// 此时程序中的单词只有唯一的
	// 单词和按大小排序
	size_t sz = 5;
	auto wc = find_if(words.begin(),words.end(),
		bind(check_size,std::placeholders::_1,sz));
	auto count = words.end() - wc;
	cout<
#include 
#include 
using namespace std;

int main()
{
	vector vec;
	istream_iterator in_iter(cin); // read ints from cin
	istream_iterator eof; // istream ``end'' 迭代器

	while(in_iter != eof)
		vec.push_back(*in_iter++);
	ostream_iterator out_iter(cout," ");

	for(auto e : vec)
		out_iter = e; // 赋值将此元素写入 cout
	cout<
#include 
#include 
using namespace std;

int main()
{
	string line;
	getline(cin,line);

	// 查找逗号分隔列表中的第一个元素
	auto comma = find(line.cbegin(),line.cend(),',');
	cout<
#include 
using namespace std;

int main()
{
    vector vec = {0,1,2,3,4,5,6,7,8,9};
    // 从后到前反转向量的迭代器
    for(auto r_iter = vec.crbegin();// 将 r_iter 绑定到最后一个元素
    		 r_iter != vec.crend();// 在第一个元素之前
    		 ++r_iter)// 递减迭代器一个元素
    	cout<<*r_iter<<" "; // prints 9, 8, 7, . . . 0
    cout<
#include 
#include 

using namespace std;

int main()
{
	vector vec;
	istream_iterator in(cin),eof;
	copy(in,eof,back_inserter(vec));

	sort(vec.begin(),vec.end());// 以“正常”顺序对 vec 进行排序
	vector vec2(vec); // vec2 是 vec 的副本

	// 反向排序:将最小的元素放在 vec 的末尾
	sort(vec.rbegin(),vec.rend());

	//prints vec
	ostream_iterator out(cout," ");
	copy(vec.begin(),vec.end(),out); // 反向排序
	cout<::reverse_iterator rev_it(it);
	cout<<*(rev_it.base())<
#include 
#include 

using namespace std;

int main()
{
	vector v1 = {0,1,2,3,4,5,6,7,8,9};
	vector v2;
	vector v3 = v1;
	// 找到第一个等于 42 的元素
	find(v1.begin(), v1.end(), 42);	
	// 找到第一个奇数元素
	find_if(v1.begin(),v1.end(),[](int i){return i % 2;});
	// 将 v1 中的元素以相反的顺序排列
	reverse(v1.begin(),v1.end());
	// 恢复原始数据	
	v1 = v3; 						
	// 将元素从 v1 以相反的顺序复制到 v2; v1 不变
	reverse_copy(v1.begin(),v1.end(),back_inserter(v2));

	for(auto i : v1)
		cout<
#include 
using namespace std;

int main()
{
	Sales_item trans;
	vector file;

	while(std::cin>>trans) // 读取交易
		file.push_back(trans);

	for(auto i : file) // 打印读取的内容
		cout<
#include 
#include 

using namespace std;
int main()
{
	vector vec;
	istream_iterator in_iter(cin);// 从cin读取整数
	istream_iterator eof;// istream ``end'' 迭代器
	// 使用 in_iter 读取 cin 存储我们在 vec 中读取的内容
	while(in_iter != eof) // 当有有效的输入要读取时
		// 后缀增量读取流并
		// 返回迭代器的旧值
		// 我们取消引用该迭代器以获取
		// 从流中读取的前一个值
		vec.push_back(*in_iter++);
	// 使用 ostream_iterator 打印 vec 的内容
	ostream_iterator out_iter(cout," ");
	copy(vec.begin(),vec.end(),out_iter);
	cout<
#include 
#include 
#include 
#include 
using namespace std;

int main()
{
	int ia[] = {27, 210, 12, 47, 109, 83};
	int val = 83;
	int *result = find(begin(ia),end(ia),val);
	cout<<"The value "< vec = {27, 210, 12, 47, 109, 83};
	val	= 42; // 我们要寻找的值

	// result2 将表示我们想要的元素,如果它在 vec 中,
	// 或者 vec.cend() 如果不是
	auto result2 = find(vec.cbegin(),vec.cend(),val);

	// 报告结果
	cout<<"The value "< lst = {"val1", "val2", "val3"};

	string sval = "a value";// 我们要寻找的值
	// 这个 find 调用查找列表中的字符串元素
	auto result3 = find(lst.cbegin(),lst.cend(),sval);

	cout<<"The value "<
#include 
#include 

using namespace std;

int main()
{
	mapword_count;// 从字符串到 size_t 的空映射
	string word;
	while(cin>>word)
		++word_count[word];
	string removal_word = "the";
	// 从map中删除条目的两种方法
	//1.by key
	//键上的擦除返回删除的元素数
	if(word_count.erase(removal_word))
		cout<<"ok:	"<::iterator where;
	where = word_count.find(removal_word);// 应该没了

	if(where == word_count.end())
		cout<<"oops: "<
#include 
#include 
#include 
using namespace std;

int main()
{
	// 从作者到标题的映射; 每个作者可以有多个标题
	multimap authors;
	// 向作者添加数据
	authors.insert({"Alain de Botton", "On Love"});
	authors.insert({"Alain de Botton", "Status Anxiety"});
	authors.insert({"Alain de Botton", "Art of Travel"});
	authors.insert({"Alain de Botton", 
		                      "Architecture of Happiness"});
	string search_item("Alain de Botton");// 我们要查找的作者
	
	auto entries = authors.count(search_item); // 元素数量
	auto iter = authors.find(search_item); // 该作者的第一个条目

	// 遍历此作者的条目数
	while(entries)
	{
		cout<second<second<second<
#include 
#include 
#include 
#include 
#include 
#include 

pair anon; // 保存两个字符串
pair word_count; // 保存一个字符串和一个 size_t
pair> line;// 保存字符串和向量

// list 初始化成对的成员
pair author{"James","Joyce"};

// 初始化对的方法
typedef pair Author;
Author proust("Marcel", "Proust"); // 构造一对
Author joyce{"James", "Joyce"}; // 列表初始化一对
Author austen = make_pair("Jane", "Austen"); // 使用 make_pair

void preliminaries(vector &v)
{
	//process v
	istream_iterator input(cin),eof;
	copy(input,eof,back_inserter(v));
	sort(v.begin(),v.end(),
		[](const string& a,const string& b){
			return a.size() < b.size();
		});
}

// 返回对的三种不同方式
// 1. list 初始化返回值
pair process(vector &v)
{
	if(!v.empty())
		return {v.back(),v.back().size()};// 列表初始化
	else
		return pair();// 显式构造的返回值
}

// 2.使用make_pair生成返回值
pair process2(vector &v)
{
	//进程c
	if(!v.empty())
		return make_pair(v.back(),v.back().size());
	else
		return pair();
}

// 3. 显式构造返回值
pair process3(vector &v)
{
	//进程c
	if(!v.empty())
		return pair(v.back(),v.back().size());
	else
		return pair();
}

int main()
{
	vector v;
	string s;
	while(cin >> s)
		v.push_back(s);

	preliminaries(v);// sort v into size order

	// 所有三个输出语句应该相同
	auto biggest = process(v);
	cout<
#include 
#include 
#include 

using namespace std;

int main()
{
	// 计算每个词在输入中出现的次数
	map word_count; // 从字符串到 size_t 的空映射
	set exclude = {"The", "But", "And", "Or", "An", "A", 
	                       "the", "but", "and", "or", "an", "a"};
	string word;
	while(cin >> word)
	{
		// 只计算不在 exclude 中的单词
		if(exclude.find(word) == exclude.end())
			++word_count[word]; // 获取并增加单词的计数器
	}

	for(const auto &w : word_count)  // 对于地图中的每个元素
	{
		// 打印结果
		cout< 1)?" times":" time")<
#include 
#include 
#include 
using namespace std;

int main()
{
	// 定义一个包含 20 个元素的向量,
	// 保存从 0 到 9 的每个数字的两个副本
	vector ivec;
	for(vector::size_type i = 0; i != 10; ++i)
	{
		ivec.push_back(i);
		ivec.push_back(i); // 每个数字的重复副本
	}

	// iset 保存来自 ivec 的唯一元素; miset 包含所有 20 个元素
	set iset(ivec.cbegin(),ivec.cend());
	multiset miset(ivec.cbegin(),ivec.cend());

	cout< set1; // 空集
	set1.insert("the"); // set1 现在有一个元素
	set1.insert("and"); // set1 现在有两个元素

	ivec = {2,4,6,8,2,4,6,8}; // ivec 现在有八个元素
	set set2; // 空集
	set2.insert(ivec.cbegin(),ivec.cend()); // set2 有四个元素
	set2.insert({1,3,5,7,1,3,5,7}); // set2 现在有八个元素

	return 0;
}

xz@xiaqiu:~/study/cpp-primer/study/build$ ./test 
20
10
20
xz@xiaqiu:~/study/cpp-primer/study/build$ 

#include 
#include 
#include 
#include 
#include 

using namespace std;
// unordered_map 版本的字数统计程序
int main()
{
	// 计算出现次数,但单词不会按字母顺序排列
	unordered_map word_count;
	string word;
	while(cin >> word)
		++word_count[word]; // 获取并增加单词的计数器
	for(const auto &w : word_count) // 对于地图中的每个元素
	{
		// 打印结果
		cout< 1) ? " times":" time")<()(sd.isbn());
}

bool eqOp(const Sales_data &lhs, const Sales_data &rhs)
{
	return lhs.isbn() == rhs.isbn();
}

// 使用我们的函数代替 hash 和 == 输入别名
using SD_multiset = unordered_multiset;

// bookstore 可以保存多个具有相同 ISBN 的 Sales_data
// 参数是桶的大小
// 以及指向哈希函数和相等运算符的指针
SD_multiset bookstore(42,hasher,eqOp);

// 如何只覆盖散列函数;
// Foo 必须有 ==
struct Foo{ string s; };

// 我们将在第 14 章中看到如何定义我们自己的 *** 作符
bool operator==(const Foo& l, const Foo& r)
{
	return l.s == r.s;
}

size_t FooHash(const Foo& f)
{
	return hash()(f.s);
}

// 使用 FooHash 生成哈希码; Foo 必须有 == 运算符
unordered_set fooSet(10,FooHash);

xz@xiaqiu:~/study/cpp-primer/study/build$ ./test 
hello world test student teacher
teacher occurs 1 time
student occurs 1 time
test occurs 1 time
world occurs 1 time
hello occurs 1 time
xz@xiaqiu:~/study/cpp-primer/study/build$ ./test 
hello hello world  test test test
test occurs 3 times
world occurs 1 time
hello occurs 2 times
xz@xiaqiu:~/study/cpp-primer/study/build$ 


#include 
#include 
#include 
#include 

using namespace std;

int main()
{
	// 计算每个单词在输入中出现的次数
	map word_count;// 从字符串到 size_t 的空映射
	string word;
	while(cin>>word)
		++word_count.insert({word,0}).first->second;

	for(auto it = word_count.cbegin(); 
			 it != word_count.cend();
			 ++it)
	{
		auto w = *it;
		cout<first<<" occurs "
			<second<<" times "<

void print(void)
{
  std::cout<<"print(void)"<
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

map buildMap(ifstream &map_file)
{
	map trans_map; // 保存转换
	string key; // 要转换的单词
	string value; // 代替使用的短语
	// 将第一个单词读入 key,将行的其余部分读入 value
	while(map_file >> key && getline(map_file, value))
		if(value.size() > 1) // 检查是否有转换
			trans_map[key] = value.substr(1); // 跳过前导空格
		else
			throw runtime_error("no rule for " + key);
	return trans_map;
}

const string & transform(const string &s, const map &m)
{
	// 实际的map工作; 这部分是程序的核心
	auto map_it = m.find(s);

	// 如果这个词在转换映射中
	if(map_it != m.cend())
		return map_it->second;  // 使用替换词
	else
		return s; // 否则返回原值不变
}

// 第一个参数是转换文件;
// 第二个是要转换的文件
void word_transform(ifstream &map_file, ifstream &input)
{
	auto trans_map = buildMap(map_file); // 存储变换

	// 出于调试目的,在构建后打印map
	cout<<"Here is our transformation map: nn";
	for(auto entry : trans_map)
		cout<<"key: "<> word)
		{
			if(firstword)
				firstword = false;
			else
				cout<<" ";// 在单词之间打印一个空格
			// 变换返回它的第一个参数或其变换
			cout<
#include 
#include 

using namespace std;

typedef int T;
struct Foo //退出main会自动关闭文件
{
	Foo(T t): val(t){}
	T val;
};

std::ostream& print(std::ostream &os, const Foo &f)
{
	os << f.val;
	return os;
}

// 工厂返回一个指向动态分配对象的指针
Foo* factory(T arg)
{
	// 根据需要处理 arg
	return new Foo(arg); 
	// 调用者负责删除这段内存
}

Foo* use_Factory(T arg)
{
	Foo *p = factory(arg);
	print(cout, *p);
	cout<>arg){
		auto p = use_Factory(arg);
		delete p; 
		// 记得从use_factory中删除内存
	}
	return 0;
}

xz@xiaqiu:~/study/cpp-primer/study/build$ ./test 
2 
2
32
32
45
45
32131
32131
32
32
32131
32131
xz@xiaqiu:~/study/cpp-primer/study/build$ 


#include 
#include 
#include 
#include 

using namespace std;

typedef int T;
struct Foo //退出main会自动关闭文件
{
	Foo(T t): val(t){}
	T val;
};

std::ostream& print(std::ostream &os, const Foo &f)
{
	os << f.val;
	return os;
}


// 工厂返回一个shared_ptr 给一个动态分配的对象
shared_ptr factory(T arg)
{
	// 根据需要处理 arg
	// shared_ptr 将负责删除此内存
	return make_shared(arg);
}

shared_ptr use_factory(T arg)
{
	shared_ptr p = factory(arg);
	print(cout,*p);
	cout<>arg)
		use_factory(arg);
	return 0;
}

xz@xiaqiu:~/study/cpp-primer/study/build$ ./test 
23
23
32
32
34234
34234
4324
4324
323
323
32133423
32133423
2313
2313
3213213
3213213
xz@xiaqiu:~/study/cpp-primer/study/build$ 


#include 
#include 
#include 
#include 
#include 

using namespace std;

size_t get_size() { return 43; }

int main()
{
	// 如果分配失败,new 返回一个空指针
	int *p1 = new int;  // 如果分配失败,new 抛出 std::bad_alloc
	int *p2 = new (nothrow) int; // 如果分配失败,new 返回一个空指针

	int i0; // 命名的、未初始化的 int 变量
	int *p0 = new int;// pi 指向一个动态分配的,// 未命名,未初始化的 int
	delete p0; // 释放pi指向的内存

	// 命名的初始化变量
	int i(1024);// i 的值为 1024
	string s(10,'9');// s 的值为 "9999999999"

	// 未命名的、初始化的动态分配对象
	int *pi = new int(1024);// pi 指向的对象的值为 1024
	string *ps = new string(10,'9'); // *ps 是 "9999999999"

	// 包含 0 到 9 值的十个元素的vector
	vector *pv = new vector{0,1,2,3,4,5,6,7,8,9};

	cout<<"*pi: "<<*pi
		<<"ti: "<begin(); b != pv->end();++b)
		cout<<*b<<" ";
	cout<
#include 
#include 
#include 
#include 
#include 
#include 

class QueryResult
{
	friend std::ostream& print(std::ostream&, const QueryResult&);
public:
	typedef std::vector::size_type line_no;
	typedef std::set::const_iterator line_it;
	QueryResult(std::string s,
				std::shared_ptr> p,
				std::shared_ptr> f):
		sought(s),lines(p),file(f){}
	std::set::size_type size() const { return lines->size(); }
	line_it begin() const { return lines->cbegin(); }
	line_it end() const { return lines->cend(); }
	std::shared_ptr> get_file() { return file; }
private:
	std::string sought; // 这个查询代表的词
	std::shared_ptr> lines; // 行
	std::shared_ptr> file; //输入文件
};

std::ostream &print(std::ostream& , const QueryResult&);



class TextQuery
{
public:
	using line_no = std::vector::size_type;
	TextQuery(std::ifstream&);
	QueryResult query(const std::string&) const;
	void display_map();// 调试辅助:打印map
private:
	std::shared_ptr> file; // 输入文件
	// 将每个单词映射到该单词出现的行集
	std::map>> wm;
	// 规范化文本:删除标点符号并使所有内容小写
	static std::string cleanup_str(const std::string&);
};

// 读取输入文件并构建行到行号的映射
TextQuery::TextQuery(ifstream &is) : file(new vector)
{
	string text;
	while(getline(is,text)) // 对于文件中的每一行
	{
		file->push_back(text);  // 记住这行文本
		int n = file->size() - 1;// 当前行号
		istringstream line(text); // 将行分隔成单词
		string word;
		while(line >> word) // 对于该行中的每个单词
		{
			word = cleanup_str(word);
			// 如果 wm 中还没有 word,则下标添加一个新条目
			auto &lines = wm[word];// 行是一个 shared_ptr
			if(!lines)// 当我们第一次看到单词时那个指针是空的
			{
				lines.reset(new set);// 分配一个新的集合
			}
			lines->insert(n); // 插入这个行号
		}
	}
}

// 书中没有提到——cleanup_str 删除
// 标点符号并将所有文本转换为小写,以便
// 查询以不区分大小写的方式运行
string TextQuery::cleanup_str(const string &word)
{
	string ret;
	for(auto it = word.begin(); it != word.end(); ++it)
	{
		if(!ispunct(*it))
			ret += tolower(*it);
	}
	return ret;
}

QueryResult TextQuery::query(const string& sought) const
{
	// 如果没有找到,我们将返回一个指向这个集合的指针
	static shared_ptr> nodata(new set);

	// 使用 find 而不是下标以避免向 wm 添加单词!
	auto loc = wm.find(cleanup_str(sought));

	if(loc == wm.end())
		return QueryResult(sought,nodata,file); // not found
	else
		return QueryResult(sought,loc->second,file);
}

ostream &print(ostream & os, const QueryResult &qr)
{
	// 如果找到单词,则打印计数和所有出现次数
	os<size()<<" "
	  <size(),"time","s")<begin() + num) <first<<" {";

		// 获取位置向量作为常量引用以避免复制它
		auto text_locs = iter->second;
		auto loc_iter = text_locs->cbegin(),
			 loc_iter_end = text_locs->cend();

		// 打印这个单词的所有行号
		while(loc_iter != loc_iter_end)
		{
			cout<<*loc_iter;

			if(++loc_iter != loc_iter_end)
				cout<<", ";
		}
		cout<<"}n";// 输出这个词的结束列表
	}
	cout<>s) || s == "q") break;
		// 运行查询并打印结果
		print(cout,tq.query(s))<
#include 
#include 

using namespace std;

int main()
{
	unique_ptr p1(new string("Stegosaurus"));
	// 从 p1 转移所有权
	//(指向字符串Stegosaurus)到p2
	unique_ptr p2(p1.release()); // 释放使 p1 为空
	cout<<*p2< p3(new string("Trex"));
	// reset 删除 p2 指向的内存
	// 并将所有权从 p3 转移到 p2
	p2.reset(p3.release());
	cout<<*p2<
#include 
#include 
#include 
#include 

// StrBlob 中友元声明所需的前向声明
class StrBlobPtr;
class StrBlob
{
	friend class StrBlobPtr;
public:
	typedef std::vector::size_type size_type;

	// 构造函数
	StrBlob() : data(std::make_shared>()){}
	StrBlob(std::initializer_listil);

	//大小 *** 作
	size_type size() const { return data->size(); }
	bool empty() const { return data->empty(); }

	// 添加和删除元素
	void push_back(const std::string &t) { data->push_back(t);}
	void pop_back();

	// 元素访问
	std::string& front();
	std::string& back();

	// StrBlobPtr 的接口
	StrBlobPtr begin();// 不能定义直到 StrBlobPtr 是
	StrBlobPtr end();

private:
	std::shared_ptr> data;
	// 如果数据] 无效,则抛出消息
	void check(size_type i, const std::string &msg) const;
};

// 构造函数
inline StrBlob::StrBlob(std::initializer_list il):
	data(std::make_shared>(il)){}

// StrBlobPtr 在尝试访问不存在的元素时抛出异常
class StrBlobPtr
{
	friend bool eq(const StrBlobPtr&, const StrBlobPtr&);
public:
	StrBlobPtr():curr(0){}
	StrBlobPtr(StrBlob &a, size_t sz = 0):wptr(a.data),curr(sz){}

	std::string& deref() const;
	StrBlobPtr& incr(); // prefix version
	StrBlobPtr& decr();  // prefix version
private:
	// 如果检查成功,检查返回一个shared_ptr给向量
	std::shared_ptr> check(std::size_t, const std::string&) const;

	//存储一个weak_ptr,这意味着底层向量可能会被破坏
	std::weak_ptr> wptr;
	std::size_t curr; // 数组中的当前位置	
};

inline std::string& StrBlobPtr::deref() const
{
	auto p = check(curr,"dereference past end");
	return (*p)[curr]; // (*p) 是这个对象指向的向量
}

inline std::shared_ptr>
StrBlobPtr::check(std::size_t i, const std::string &msg) const
{
	auto ret = wptr.lock();// 向量还在吗?
	if(!ret)
		throw std::runtime_error("unbound StrBlobPtr");

	if(i >= ret->size())
		throw std::out_of_range(msg);
	return ret;// 否则,返回一个 shared_ptr 给向量
}

// 前缀:返回对递增对象的引用
inline StrBlobPtr& StrBlobPtr::incr()
{
	// 如果 curr 已经指向容器的末尾,则不能增加它
	check(curr,"increment past end of StrBlobPtr");
	++curr;// 推进当前状态
	return *this;
}

inline StrBlobPtr& StrBlobPtr::decr()
{
	// 如果 curr 为零,递减它会产生一个无效的下标
	--curr;// 将当前状态移回一个元素}
	check(-1,"decrement past begin of StrBlobPtr");
	return *this;
}

// StrBlob 的开始和结束成员

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5698449.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存