容器、迭代器

1,顺序容器概述

vector可变大小数组;支持随机访问。尾部之外插入或删除数据可能很慢。 vector<变量> 名称; 使用:名称[]。
deque双端队列;支持快速随机访问。在头尾位置插入/删除很快。
list双向链表。不支持随机访问;只支持双向顺序访问;在list中任何位置进行插入/删除速度很快。
forward_list单向链表。不支持随机访问;在链表中任何位置进行插入/删除速度很快。
array固定大小数组。不能添加删除元素。

vector,deque可以通过下标快速访问,但是增添或减少会耗费大量的代价。
list ,forward_list不支持快速访问,他访问元素必须遍历所有元素。但是增添或减少会更加方便。

选择容器原则:

尽量使用vector;
如果需要在容器中间插入或删除元素,则选择list或者forward_list。
如果不确定使用哪种容器,则可以再程序中只使用vector和list的公共操作:使用迭代器,不使用下标避免随机访问

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    vector<int> v;  //v是存放int类型变量的可变长数组,开始时没有元素
    for (int n = 0; n<5; ++n)
        v.push_back(n);  //push_back成员函数在vector容器尾部添加一个元素
    vector<int>::iterator i;  //定义正向迭代器
    for (i = v.begin(); i != v.end(); ++i) {  //用迭代器遍历容器
        cout << *i << " ";  //*i 就是迭代器i指向的元素
        *i *= 2;  //每个元素变为原来的2倍
    }
    cout << endl;
    //用反向迭代器遍历容器
    for (vector<int>::reverse_iterator j = v.rbegin(); j != v.rend(); ++j)
        cout << *j << " ";
    return 0;
}

程序的输出结果是:
0 1 2 3 4
8 6 4 2 0

后置++要多生成一个局部对象 tmp,因此执行速度比前置的慢。同理,迭代器是一个对象,STL 在重载迭代器的++运算符时,后置形式也比前置形式慢。在次数很多的循环中,++i和i++可能就会造成运行时间上可观的差别了。因此,本教程在前面特别提到,对循环控制变量i,要养成写++i、不写i++的习惯。

vector::iterator i; //定义正向迭代器
vector::reverse_iterator j;//用反向迭代器遍历容器
const_reverse_iterator;不能修改元素的迭代器

2,容器操作:通过迭代器做传输作用(就看做读取其内存地址去使用,不涉及其元素本身)

类型别名作用
iterator迭代器类型
const_iterator可以读取元素,但不能修改元素迭代器类型
value_type元素类型
size()元素数目(不支持forward_list)
empty()是否为空
clear()清空所有元素
begin()end()指向首元素和尾元素之后位置的迭代器
cbegin(),cend()返回const_iterator;对于只读不改变元素的算法尽量使用这个

加上作用域运算符(:😃 例如:list::iterator iter;
iterator:此容器类型的迭代器类型
const_iterator:不能修改元素迭代器类型
value_type:元素类型

容器类型:容器<类型名>::类型别名 变量名称(也可以称为迭代器)
类型别名可以看做是个类型。
我们可以通过变量名称来使用其成员,成员通过(begin 和end)来实现其值的改变。
例如:list::iterator iter;
iter.begin() , iter.end();
++begin;

1)容器拷贝:

为了创建一个容器为另一个容器拷贝,2个容器类型及其元素类型必须匹配。
当传递迭代器参数来拷贝一个范围时,就不用了考虑容器类型了。

list<string>a1={"c","b"};
vector<int>a2={1,2};

list<string> b1(a1);//正确
deque<string>b2(a1)//错误
vector<string>b3(a2)//错误 元素类型不匹配

vector<int>b4(a1.begin(),a1.end());//正确
b4容器必须和范围中的元素数目一致,新容器的每个元素都用范围中对应元素的值进行初始化。

假设it为a1中的某个元素
vector<int>b4(a1.begin(),it)

2)顺序容器增加操作

c.push_back(t)在尾部创建一个值为t的元素
c.push_front(t)在头部创建一个值为t的元素
c.insert(p,t)在迭代器p指向的元素之前创建一个值为t的元素
c.insert(p,n,t)在迭代器p指向的元素之前创建n个值为t的元素

重要提示:在vector string,deque插入元素会使指向容器的迭代器、引用、和指针失效

3)访问元素

at()只适用vector、string、deque、array
c[]同上
back()返回尾元素的引用,不适用forward_list
front()首元素的引用。

4)删除元素

这些操作会改变容器大小,所以不适合array

pop_back()删除尾元素
pop_front()删除头元素
clear()清空元素

删除deque中除首尾位置之外的任何元素都会使所有迭代器、引用、指针失效。指向vector、string中删除点之后位置的迭代器、引用、指针都会失效

删除元素的成员函数并不会检查其参数。再删除元素之前,程序员必须确保其存在。

5)容器操作可能会使迭代器失效

向容器内添加元素:
如果容器是vector、string,且存储空间被重新分配,则指向容器的迭代器、引用、指针都会失效
对于deque,插入除首尾位置之外的任何元素都会使所有迭代器、引用、指针失效。如果在首尾位置添加元素,迭代器会失效,引用、指针不会失效。

删除元素
对于deque,删除deque中除首尾位置之外的任何元素都会使所有迭代器、引用、指针失效。如果删除首元素,不影响。如果删除尾元素,则尾后迭代器会影响,但是其他迭代器、指针、引用不受影响
对于vector、string:指向vector、string中删除点之后位置的迭代器、引用、指针都会失效。指向之前的不受影响。

建议:
当你使用迭代器,最小化要求迭代器必须保持有效性。
由于向迭代器增添或者删除可能会使迭代器失效,所以必须保证每次改变容器大小都重新正确的定义迭代器。对于vector、deque、string尤为重要。

注意看c++primer的355页的2段代码。

3.vector对象是如何增长的

www.baidu.com

所有都是手敲的,老铁给个赞。我也会持续更新有关c++11的一切。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值