31:知识点1:容器的改变可能会使迭代器失效,插入和删除各有其相关的规则,P315.
知识点2:必须保证每次改变容器的操作之后都正确的重新定位迭代器的操作
知识点3:调用erase()之后,其返回的迭代器指向的是序列中的下一个元素,其返回的迭代器可以用来更新
知识点4:向容器插入元素后,对于list和forward_list,指向容器的迭代器、指针、引用皆有效
对于list
advance(iter, 2);
对于forward_list
#include
#include
using namespace std;
void main()
{
forward_list 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
#include
using namespace std;
void main()
{
list 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
#include
using namespace std;
void main()
{
vector 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
#include
#include
using namespace std;
void func(int val)
{
vector 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
请按任意键继续. . .