C++定义了一些内置类型,如字符型、整型、浮点型等。C++还提供了可用于自定义数据类型的机制,标准库正式利用这些机制定义了许多更复杂的类型,如string、vector类型。标准库将负责管理与内存元素相关的内存。要使用这些标准库类型,必须要加入其头文件,这些头文件的内容在预处理过程中会被复制到程序中,称为真正源代码的一部分。
如#include<vector> using std::vecor; #include<string> using std::string;
vector是同一种类型对象的集合,每个对象都有一个对应的整数索引值(下标),因此可以生动地称vector为容器。需要注意的是,vector是一个模板,而vector<int>、vector<string>才是数据类型。下面我们将从。。。。。几个方面对vector容器进行学习。
1)vector对象的定义及初始化
vector<T> v1 | vector 保存类型为T,默认构造函数,v1为空 |
vector<T> v2(v1) | v2是v1的一个副本 |
vector<T> v3(n,i) | v3包含n个值为i的元素 |
vector<T> v4(n) | v4含有值初始化的元素的n个副本 |
如:vector<int> ivec1;//定义了一个int类型的vecto空r容器
vector<int> ivec2 (ivec1);//创建的ivec2是ivec1的副本
vector<string> svec (ivec1);//error,副本与原始对象数据类型不同
若没有指定元素的初始化式,vector会默认对元素进行初始化。若vector保存内置类型元素,那么标准库将使用0值创建元素初始化式;若vector保存的是含有构造函数的类类型元素,标准库将用该类型的默认构造函数创建元素初始化式。
如:vector<int> fvec(10);内置类型元素,十个创建的int元素为0
vector<string> svec(10);类类型元素,根据string规则,每个元素为空
2)vector对象的操作
vector标准库提供了表2几种重要的操作.。
v.empty() | 如果v为空,则返回true,否则返回false |
v.size() | 返回v中元素的个数 |
v.push_back(t) | 在v的末尾增加一个值为t的元素 |
v[n] | 返回v中位置为n的操作 |
v1 = v2 | 把v1的元素替换为v2中元素的副本 |
v1 == v2 | 如果v1与v2相等,返回true |
!=,<,<=,>,>= | 保持这些操作符惯有含义 |
a.成员函数size返回相应vector类定义的size_type的值,在使用size_type类型时,应指出该类型在哪定义以及数据类型
例如:vector<int>::size_type //ok vector::size_type //error
b.可以使用v.push_back()操作进行“插入(push)”到vector对象“后面(back)”;
例如:string word;
vector<string> text;
while(cin >> word)
{
text.push_back(word); //append word to text
}
c.vector下标操作 vector的下标操作只能用来获取数据,不能用来添加数据,但可以用来对元素进行赋值,而且只能对已存在的元素进行下标操作。
例如: for (vector<int >::size_type ix=0;ix!=ivec._size();++ix)
{
ivec[ix] = 0; //ok,当ivec为空时,也ok
}
添加操作时,许多人会以为这么写:
vector<int> ivec;
for(vector<int>::size_type ix=0;ix !=10;++ix)
ivec[ix] = ix;
上面程序试图在ivec中插入10个元素,但失败了,但还是可以采用v.push_back()进行操作:
for(vector<int>::size_type ix=0;ix !=10;++ix)
ivec.push_back(ix);
3)迭代器的应用
迭代器是一种检查容器内元素并遍历元素的数据类型。若一种数据类型支持一组确定的操作(这些操作可用来遍历容器内的元素,并访问容器内的元素),我们就称这种类型为迭代器。事实上,所有标准库容器都定义了相应的迭代器类型,只有少数容器直尺下标操作。现代C++程序更倾向于使用迭代器而不是下表操作,即使对直尺下标操作的vector类型也是如此。
(1)vector定义了自己的迭代类型:
vector<int>::iterator iter;
(2)begin和end操作
begin()函数用于返回迭代器指向的第一个元素(容器非空),end();函数返回迭代器指向vector的“末端元素的下一个”,通常称为超出末端迭代器(off-the-end iterator)。end()函数常被用作哨兵来作为边界条件。若vector为空,begin和end返回相同。
(3)vector迭代器的运算
我们可以使用解引用操作符(*)来访问迭代器当前所指向的元素,解引用操作符返回迭代器当前所指向的元素。
例如, 假设iter指向vector对象ivec的第一个元素,那么 *iter和ivec[0]指向容器第一个元素, *iter = 0;//将该元素的值赋为0。
对于int对象,利用自增符号 ++iter,将迭代器“向前移动一个位置”。在上例中 ++iter指向第二个元素。
可以用 == 或 !=操作符比较两个迭代器,若两个迭代器对象指向同一个元素,则相等,否则不相等。
example1 将一个vector<int>型的ivec变量所有元素重置为0:
for (vector<int>::size_type ix=0;ix !=ivec.size();++ix)
ivec[ix] = 0;//利用下标操作置零
for (vector<int>::iterator iter = ivec.begin();iter !=ivec.end(); ++iter)
*iter = 0;//利用迭代器操作置零
除了自增自减运算之外,迭代器还可以进行算术操作: iter + n;iter - n;表示一个迭代器,其位置在iter所致元素之前或之后n个元素的位置;可以利用 iter1 - iter2 计算两个迭代器对象的距离。
example2:要访问位于vector的中间元素:
vector<int>::iterator mid = vi.begin() + vi.size()/2;