C++Primer第五版 第九章习题答案(31~40)

31:知识点1:容器的改变可能会使迭代器失效,插入和删除各有其相关的规则,P315.

知识点2:必须保证每次改变容器的操作之后都正确的重新定位迭代器的操作

知识点3:调用erase()之后,其返回的迭代器指向的是序列中的下一个元素,其返回的迭代器可以用来更新

知识点4:向容器插入元素后,对于list和forward_list,指向容器的迭代器、指针、引用皆有效

 

对于list

advance(iter, 2);

对于forward_list

#include<iostream>
#include<forward_list>
using namespace std;
void main()
{
	forward_list<int> vi = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	auto prev = vi.before_begin();
	auto curr = vi.begin();
	while (curr != vi.end())
		if (*curr % 2)
		{
			curr = vi.insert_after(prev, *curr);    //返回迭代器,指向新插入元素
			prev = ++curr;
			++curr;
		}
		else
			curr = vi.erase_after(prev);
	for (auto a : vi)
		cout << a << ends;
	cout << endl;
	system("pause");
}

32:首先明确运算符的顺序:++高于*解引用符号。

       分析:对于容器vi = {0,1,2,3,4,5,6,7,8,9}; iter = vi.insert(iter,*iter ++); 后置++虽然优先级高于解引用*,但是iter是拿递增之前的迭代器去解引用,所以第一次的插入操作vi.insert(iter,*iter ++)中,第二个参数*iter ++ 的结果是1,而第一个参数iter则为递增之后的迭代器(此时指向2),故应该是在2之前插入1。 但是,返回的是插入元素的迭代器,故,iter又重新指向0,1,1,2,3,4,5,6,7,8,9的第二个1。这样之后的操作会无限循环的再2前面插入1。因此需要手动移动迭代器,代码如下:

       

#include<iostream>
#include<list>
using namespace std;
void main()
{
	list<int> vi = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
	auto iter = vi.begin();
	while (iter != vi.end())
		if (*iter % 2)
		{
		    iter = vi.insert(iter, *iter++);
		    ++iter;
		}
		else
			iter = vi.erase(iter);
	for (auto a : vi)
		cout << a << ends;
	cout << endl;
	system("pause");
}

       

33:知识点:不要保存end返回的迭代器,因为你对容器的操作会使得这个迭代器失效。(vector,string,deque)

程序会崩溃,因为begin迭代器的值在插入一个元素之后已经失效。

34:老生常谈的问题了,insert()返回的迭代器是指向新插入元素的,如若进行插入元素,需要加两次才能跳过当前元素。

35:知识点:                                                                              P318

1、size():容器已经保存的元素的数目。

2、capacity():在不重新分配内存空间的前提下它最多可以保存多少元素。

3、shrink_to_fit():请求编译器将容器的 capacity() 减少为与 size() 相同大小,但编译器不一定会执行。

4、reserve(n):为容器分配至少能容纳 n 个元素的内存空间。

5、resize(n):将容器存储的元素变为 n 个,原来元素多余n的舍去,不够的补齐(默认初始化如算术类型,不能默认初始化的需要显示初始,或定义默认构造函数。P314)

[注]shrink_to_fit 只适用于 vector、string 和 deque。

capacity 和 reserve 只适用于 vector 和 string。

36:容器 capacity 显然大于等于 size。

37:知识点:vector,string 有capacity是因为其内存是连续存储的,而 list 不是。再则 array 容器的大小是固定的,capacity 没意义。

38:

#include<iostream>
#include<vector>
using namespace std;
void main()
{
	vector<int> vi;
	cout << "vi.size(): " << vi.size() << endl;
	cout << "vi.capacity(): " << vi.capacity() << endl;
	vi.push_back(1);
	cout << "vi.size(): " << vi.size() << endl;
	cout << "vi.capacity(): " << vi.capacity() << endl;
	vi.erase(vi.begin());
	cout << "vi.size(): " << vi.size() << endl;
	cout << "vi.capacity(): " << vi.capacity() << endl;
	system("pause");
}

39:知识点:

reserve() 为容器分配至少能容纳 n 个元素的内存空间,但只能保证扩大会成功。

resize() 只改变元素个数,不会改变内存。

40:[注]不同编译器结果可能不同。

#include<iostream>
#include<string>
#include<vector>
using namespace std;
void func(int val)
{
	vector<string> svec;
	svec.reserve(1024);
	for (int i = 0; i < val; ++i)
		svec.push_back("aa");
	cout << "svec_size: " << svec.size() << endl;
	cout << "svec_capacity: " << svec.capacity() << endl;
}
void main()
{
	func(256);
	func(512);
	func(1024);
	func(2048);
	system("pause");
}

结果:

svec_size: 256
svec_capacity: 1024
svec_size: 512
svec_capacity: 1024
svec_size: 1024
svec_capacity: 1024
svec_size: 2048
svec_capacity: 2304
请按任意键继续. . .

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值