vector是同一种类型的对象的集合,每个对象都有一个对应的整数索引值。vector成为容器,因为它能包含其他对象,所有对象必须是同一种类型。
#include<vector>
using std::vector;
注意:vector是一种类模板,不是一种数据类型,它可以来定义任意多种数据类型。如vector<int>和vector<string>都是数据类型。
1.vector对象的定义和初始化
(1)vector<T> v1; vector保存类型为T的对象。默认构造函数v1为空。
(2)vector<T> v2(v1); v2是v1的一个副本
(3)vector<T> v3(n,i); v3包含n个值为i的元素。
(4)vector<T> v4(n); v4含有值初始化的元素的n个副本。
重点:vector对象动态增长
vector对象(以及其他标准容器对象)的重要属性就在于可以在运行时高效地添加元素。因为vector增长的效率高,在元素已知的情况下,最好是动态地添加元素。
2.值初始化
如果没有指定元素的初始化式,那么标准库将自行提供一个元素初始值进行值初始化。
如:vector<int> fvec(10);//10个元素都初始化为0
vector<string> svec(10); //10个元素都是空字符串
3.vector对象的操作
(1)size
empty和size操作类似于string对象的相关操作。成员函数size返回相应vector类定义的size_type的值。
注意:使用size_type类型时,必须指出该类型是哪里定义的。vector类型总是包括vector的元素类型
vector<int>::size_type//正确
vector::size_type //错误
(2)向vector添加元素
push_back()操作接受一个元素值,并将它作为一个新的元素添加到vector对象的后面,也就是“插入(push)”到vector对象的“后面(back)”:
string word;
vector<string> text;
while(cin>>word)
text.push_back(word);
(3)vector下标的操作
vector元素的位置从0开始。
string word;
vector<string> text;
while(cin>>word)
text.push_back(word);
for(vector<string>::size_type ix=0; ix!=text.size(); ++ix)
text[ix] = "0";
for(vector<string>::size_type ix=0;ix!=text.size();++ix)
cout<<text[ix]<<endl;
注意:上例,即使text为空,for循环也会正确执行。text为空则调用size返回0。
C++程序员习惯于习惯优先选用!=而不是<来编写循环判断条件。
4.下标操作不添加元素
注意:必须是已存在的元素才能用下标操作符进行索引。通过下标操作符进行赋值时,不会添加任何元素。
仅能够对己存在的元素进行下标操作。
5.vector的迭代器
(1)标准库为每一种标准容器定义了一种迭代器类型,如:vector<int>::iterator iter;
需要注意的是iter是迭代器,vector<int>是迭代器类型。
(2)begin和end操作
每个容器都定义了一对命名为begin和end的函数,用于返回迭代器。
vector<int>::iterator iter = xxx.begin();假设xxx不为空,初始化后iter指向该元素的xxx[0]。
由end操作返回的迭代器指向vector的“末端元素的下一个”。通常称为超出末端迭代器,表明它指向了一个不存在的元素。如果vector为空,begin返回的迭代器与end返回的迭代器相同。
由end操作返回的迭代器并不指向vector中任何实际的元素,相反,它只是起一个哨兵的作用,表示我们已处理完vector中所有的元素
6.vector的迭代器的自增和解引用运算符(*操作符)
vector<int>::iterator iter = xxx.begin();
*iter = 0;// *iter和xxx[0]就是指向同一个元素。
++iter指向第二个元素。
注意:由于end操作返回的迭代器不指向任何元素,因此不能对它进行解引用或自增操作。
vector<int> fvec(10,20);
//重置值,方法一
for(vector<int>::size_type ix=0; ix!=fvec.size(); ++ix)
fvec[ix] = 10;
for(vector<int>::size_type ix=0;ix!=fvec.size();++ix)
cout<<fvec[ix]<<endl;
//方法二
for(vector<int>::iterator iter=fvec.begin();iter!=fvec.end();++iter )
*iter = 15;
for(vector<int>::size_type ix=0;ix!=fvec.size();++ix)
cout<<fvec[ix]<<endl;
7.const_iterator
每种容器类型定义了一个名为const_iterator的类型,该类型只能用于读取容器内元素,但不能改变其值。
vector<int> fvec(10,20);
for(vector<int>::iterator iter=fvec.begin();iter!=fvec.end();++iter )
*iter = 15;
//方法1
for(vector<int>::size_type ix=0;ix!=fvec.size();++ix)
cout<<fvec[ix]<<endl;
//方法2
for(vector<int>::const_iterator iter=fvec.begin();iter!=fvec.end();++iter)
cout<<*iter<<endl;
注意:使用const_iterator类型时,我们可以得到一个迭代器,它自身的值可以改变,但不能用来改变其所指向的元素的值。可以对迭代器进行自增以及使用解引用操作符来读取值,但不能对改元素赋值。
const_iterator对象与const的iterator对象混肴起来,声明一个const迭代器时,必须初始化容器。一旦被初始化后,就不能改变它的值。
vector<int> fvec(10,20);
const vector<int>::iterator cit = fvec.begin();
*cit = 1;//正确
++cit; //错误
const的iterator几乎没什么作用。
8.迭代器的算术操作
注意:任何改变vector长度的操作都会使已存在的迭代失效,例如,在调用push_back之后,就不能再信赖指向vector的迭代器的值了。