C++ primer 读书笔记系列——(6)顺序容器
2010-09-03 22:27
295 查看
顺序容器类型:
顺序容器:
vector 支持快速随即访问
list 支持快速插入/删除
deque 双端队列
顺序容器适配器:
stack 后进先出栈(LIFO)
queue 先进先出队列(FIFO)
priority_queue 有优先级管理的队列
(一)顺序容器的定义
1.容器的定义和初始化
代码运行结果:
105 106 107 108 109
100 101 102 103 104 105 106 107 108 109
2.容器内元素的类型约束条件
a.元素类型必须支持赋值运算
b.元素类型的对象必须可以复制
例如:我们定义了一个类foo,但该类没有定义默认的构造函数,但提供了一个需要int型形参的构造函数;
现在,考虑下面的声明:
vector<foo> empty; //ok;no need for element default constructor
vector<foo> bad(10) //error;no default constructor for foo
vector<foo> ok(10,1) //ok:each element initialized to1
(二)迭代器和迭代器范围
迭代器的解引用操作:(*iter).mem与iter->mem等效。
使迭代器失效的容器操作:一些容器操作会修改容器内在状态或移动容器内元素,这样的操作会使所有被移动的元素的迭代器失效,也可能同时使其他迭代器失效,使用无效迭代器是没有意义的,可能会导致与悬垂指针相同的问题。 例如:每种容器都定义了一种或多种erase函数,这些函数提供了删除元素的功能,当执行此函数后,指向已删除元素的跌倒器是没有任何意义的,毕竟,该迭代器指向了容器中不再存在的元素。
无法检查迭代器是否有效,也无法通过测试来发现迭代器是否已经失效。任何无效迭代器的使用都可能导致运行时出错。但程序不一定崩溃,否则,检查这种错误会容易些。
(三)顺序容器的操作
1.reverse_iterator 和 rbegin,rend的结合用法:
程序执行结果为:
109 108 107 106 105 104 103 102 101 100
2.在顺序容器中添加元素
c.push_back(t) //在c的尾部添加值为T的元素。返回void类型
c.push_front(t) //在c的第一个元素的前面添加值为t的元素,返回void类型,只适用于list和deque容器类型
c.insert(p,t) //在迭代器p的前面插入值为t的元素,返回新添加元素的迭代器
c.insert(p,n,t) //在迭代器p的前面插入n个值为t的元素,返回void类型
c.insert(p,b,e) //在迭代器p所指向的元素前面插入由迭代器p和e标记的范围内的元素,返回void类型
程序运行结果:
9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9
11 11 11 11 11 11 11 11 11 11 9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9
11 11 11 11 11 11 11 11 11 11
可以看到,vector虽然不支持push_front()操作,但可以用insert(s.front(),t)来替代此操作;
3.容器大小的操作
c.size() 返回容器中元素的个数
c.max_size() 返回容器中可容纳的最多的元素的个数
c.empty() 返回标记容器大小是否为0的布尔值
c.resize(n) 调整容器元素的大小,使其可容纳n个元素
c.resize(n,t) 调整容器元素的大小,使其可容纳n个元素,所有新添加的元素为t;
程序运行结果:
the elements of ivec is:
0 1 2 3 4 5 6 7 8 9
ivec's size is: 10
ivec's max_size is: 1073741823
after resize to 25,now the elements of ivec is
0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
now the size of ivec is:25
now the max_size of ivec is:1073741823
after resize to 50,now the elements of ivec is
0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 121 121 121 121 121 121 121 12
1 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121
now the size of ivec is:50
now the max_size of ivec is:1073741823
事实上,resize操作可能会使迭代器失效,在vector或deque上做resize操作可能会使其所有的迭代器都失效。
对于所有的容器类型,如果resize压缩了容器大小,则指向已删除的元素的迭代器失效。
顺序容器:
vector 支持快速随即访问
list 支持快速插入/删除
deque 双端队列
顺序容器适配器:
stack 后进先出栈(LIFO)
queue 先进先出队列(FIFO)
priority_queue 有优先级管理的队列
(一)顺序容器的定义
1.容器的定义和初始化
#include<iostream> #include<vector> using namespace std; int main() { vector<int> ivec; for(vector<int>::size_type ix=0;ix!=10;ix++) //初始化ivec; { ivec.push_back(100+ix); } for(vector<int>::const_iterator iter1=ivec.begin()+ivec.size()/2;iter1!=ivec.end();iter1++) //打印ivec { cout<<*iter1<<" "; } cout<<endl; vector<int> ivec1(ivec.begin(),ivec.end()); //将ivec1初始化为ivec的一个副本,此句可置换为ivec1(ivec); for(vector<int>::const_iterator iter=ivec1.begin();iter!=ivec1.end();iter++) //打印ivec1 { cout<<*iter<<" "; } cout<<endl; return 0; }
代码运行结果:
105 106 107 108 109
100 101 102 103 104 105 106 107 108 109
2.容器内元素的类型约束条件
a.元素类型必须支持赋值运算
b.元素类型的对象必须可以复制
例如:我们定义了一个类foo,但该类没有定义默认的构造函数,但提供了一个需要int型形参的构造函数;
现在,考虑下面的声明:
vector<foo> empty; //ok;no need for element default constructor
vector<foo> bad(10) //error;no default constructor for foo
vector<foo> ok(10,1) //ok:each element initialized to1
(二)迭代器和迭代器范围
迭代器的解引用操作:(*iter).mem与iter->mem等效。
使迭代器失效的容器操作:一些容器操作会修改容器内在状态或移动容器内元素,这样的操作会使所有被移动的元素的迭代器失效,也可能同时使其他迭代器失效,使用无效迭代器是没有意义的,可能会导致与悬垂指针相同的问题。 例如:每种容器都定义了一种或多种erase函数,这些函数提供了删除元素的功能,当执行此函数后,指向已删除元素的跌倒器是没有任何意义的,毕竟,该迭代器指向了容器中不再存在的元素。
无法检查迭代器是否有效,也无法通过测试来发现迭代器是否已经失效。任何无效迭代器的使用都可能导致运行时出错。但程序不一定崩溃,否则,检查这种错误会容易些。
(三)顺序容器的操作
1.reverse_iterator 和 rbegin,rend的结合用法:
#include<iostream> #include<vector> using namespace std; int main() { vector<int> ivec; for(vector<int>::size_type ix=0;ix!=10;ix++) //初始化ivec; { ivec.push_back(100+ix); } vector<int>::reverse_iterator iter=ivec.rbegin(); // rbegin()返回的为逆序迭代器,该迭代器指向容器最后一个元素 vector<int>::reverse_iterator iter1=ivec.rend(); //rend()返回的为逆序迭代器,该迭代器指向容器第一个元素的前一个位置 for(; iter!=iter1;iter++) //打印ivec; { cout<<*iter<<" "; } cout<<endl; return 0; }
程序执行结果为:
109 108 107 106 105 104 103 102 101 100
2.在顺序容器中添加元素
c.push_back(t) //在c的尾部添加值为T的元素。返回void类型
c.push_front(t) //在c的第一个元素的前面添加值为t的元素,返回void类型,只适用于list和deque容器类型
c.insert(p,t) //在迭代器p的前面插入值为t的元素,返回新添加元素的迭代器
c.insert(p,n,t) //在迭代器p的前面插入n个值为t的元素,返回void类型
c.insert(p,b,e) //在迭代器p所指向的元素前面插入由迭代器p和e标记的范围内的元素,返回void类型
#include<iostream> #include<vector> #include<list> using namespace std; int main() { list<int> ivec; for(list<int>::size_type ix=0;ix!=10;ix++) //在ivec尾部压入10个元素 { ivec.push_back(ix); } for(list<int>::size_type iy=0;iy!=10;iy++) //在ivec头部压入10个元素 { ivec.push_front(iy); } for(list<int>::const_iterator iter=ivec.begin();iter!=ivec.end();iter++) //输出ivec { cout<<*iter<<" "; } cout<<endl; ivec.insert(ivec.begin(),10,11);//在ivec的头部添加10个元素值11 for(list<int>::iterator iter3=ivec.begin();iter3!=ivec.end();iter3++) //输出ivec { cout<<*iter3<<" "; } cout<<endl; vector<int> ivec1; ivec1.insert(ivec1.begin(),10,11); //在容器ivec1第一个元素前面插入10个11 for(vector<int>::const_iterator iter1=ivec1.begin();iter1!=ivec1.end();iter1++) //打印ivec1 { cout<<*iter1<<" "; } cout<<endl; return 0; }
程序运行结果:
9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9
11 11 11 11 11 11 11 11 11 11 9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9
11 11 11 11 11 11 11 11 11 11
可以看到,vector虽然不支持push_front()操作,但可以用insert(s.front(),t)来替代此操作;
3.容器大小的操作
c.size() 返回容器中元素的个数
c.max_size() 返回容器中可容纳的最多的元素的个数
c.empty() 返回标记容器大小是否为0的布尔值
c.resize(n) 调整容器元素的大小,使其可容纳n个元素
c.resize(n,t) 调整容器元素的大小,使其可容纳n个元素,所有新添加的元素为t;
#include<iostream> #include<vector> #include<list> using namespace std; int main() { vector<int> ivec; for(vector<int>::size_type ix=0;ix!=10;ix++) //初始化ivec { ivec.push_back(ix); } //输出Ivec信息 cout<<"the elements of ivec is:"<<endl; for(vector<int>::iterator iter1=ivec.begin();iter1!=ivec.end();iter1++) { cout<<*iter1<<" "; } cout<<endl; cout<<"ivec's size is: "<<ivec.size()<<endl; cout<<"ivec's max_size is: "<<ivec.max_size()<<endl<<endl; //使用resize(t)函数重新调整ivec大小,并显示ivec信息 ivec.resize(25); cout<<"after resize to 25,now the elements of ivec is"<<endl; for(vector<int>::iterator iter=ivec.begin();iter!=ivec.end();iter++) { cout<<*iter<<" "; } cout<<endl; cout<<"now the size of ivec is:"<<ivec.size()<<endl; cout<<"now the max_size of ivec is:"<<ivec.max_size()<<endl<<endl; //使用resize(n,t)函数重新调整ivec大小,并显示ivec信息 ivec.resize(50,121); cout<<"after resize to 50,now the elements of ivec is"<<endl; for(vector<int>::iterator iter2=ivec.begin();iter2!=ivec.end();iter2++) { cout<<*iter2<<" "; } cout<<endl; cout<<"now the size of ivec is:"<<ivec.size()<<endl; cout<<"now the max_size of ivec is:"<<ivec.max_size()<<endl<<endl; return 0; }
程序运行结果:
the elements of ivec is:
0 1 2 3 4 5 6 7 8 9
ivec's size is: 10
ivec's max_size is: 1073741823
after resize to 25,now the elements of ivec is
0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
now the size of ivec is:25
now the max_size of ivec is:1073741823
after resize to 50,now the elements of ivec is
0 1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 121 121 121 121 121 121 121 12
1 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121 121
now the size of ivec is:50
now the max_size of ivec is:1073741823
事实上,resize操作可能会使迭代器失效,在vector或deque上做resize操作可能会使其所有的迭代器都失效。
对于所有的容器类型,如果resize压缩了容器大小,则指向已删除的元素的迭代器失效。
相关文章推荐
- C++ primer 读书笔记系列——(6)顺序容器(二)
- C++ primer 读书笔记系列——(6)顺序容器(三)之再谈string类型和容器适配器
- C++ Primer 读书笔记: 第9章 顺序容器
- 《C++ Primer》读书笔记第九章-1- 顺序容器概述 And 容器库概览
- 《C++ Primer》读书笔记第九章-2-顺序容器操作 And vector增长问题
- c++ primer 读书笔记 第九章 顺序容器有那些 vector list deque stack queue priority-queue
- 《C++ Primer 4th》读书笔记 第9章-顺序容器
- 《C++ primer(第四版)》读书笔记8-第9章 顺序容器
- C++ Primer 读书笔记 Chapter 9 顺序容器
- 《C++ Primer》读书笔记-第九章 03 顺序容器操作
- 读书笔记:C++ primer 5th edition--chapter9.顺序容器
- C++ Primer 第四版读书笔记(八)之顺序容器(续)
- C++ Primer 第四版读书笔记(八)之顺序容器
- C++ primer 读书笔记 第九章 顺序容器
- 《C++ Primer》读书笔记-第九章 01 顺序容器
- C++ primer 读书笔记系列——(7)关联容器
- 读书笔记《C++ Primer》第五版——第九章 顺序容器
- 《C++ Primer》读书笔记——第九章_顺序容器
- C++ Primer学习系列(3):函数/标准IO库/顺序容器
- 读书笔记:C++ Primer系列(5)—— 标准库类型之string