vector容器与数组非常相似,他们都存放一组具有相同类型数据的元素,其元素是以连续的方式存放——每一个元素紧挨着前一个元素存储。他们的元素没有独立的名字,所以对元素进行访问时都需要一种相应迭代器来历遍元素或使用下标形式访问,vector容器使用容器的iterator类型,相应的,数组使用指针。或许可以这样理解:数组是一种特殊的vector容器,指针是一种特殊的迭代器。
vector容器与数组
一、定义:vector<int> a; //定义一个名为i的整形容器,注意,此时容器中没有元素
vector<int> a(n); //创建有n个值初始化整形元素的容器i
int a[n]; //创建一个长度为n的整形数组,注意,数组中的n必须是常量表达式
由以上的定义比较,容器中的<int>对应数组中的int,容器中的a对应数组名a,容器中的vector…(n)对应[n]。
但实质上 vector<int> a(n);和 int a[n];是不一样的。由于所有容器类型都定义了默认构造函数,用于创建指定类型的空容器对象,所以在定义vector<int> a(n);时,这个容器里的n个元素都初始化为0。
而数组int a[n];则需要看是在哪里定义的:
*在函数体外定义的内置数组,其元素均初始化为0;
*在函数体内定义的内置数组,其元素无初始化;
*不管数组在哪里定义,如果其元素为类类型,则自动调用该类的默认构造函数进行初始化;如果该类没有默认构造函数,则必须为该数组的元素提供显示初始化。
二、赋值
因为vector容器和数组都支持下标操作,所以可以使用下标操作对vector容器和数组中的元素逐个赋值。
如:for(size_t i=0;i!=n;++i)
a[i]=0;//用下标操作对含有n个整形元素的数组元素依次赋值,注意数组下标的类型是size_t
for(vector<int>::size_type i=0;i!=n;++i)
a[i]=0;//用下标操作对含有n个vector<int>元素的vector容器元素依次赋值,注意vector容器下标的类型是vector::size_type
但是数组不允许直接复制和赋值,vector容器却可以
如:
int a[n]={0,1,2};//n是常量3
int a1[ ](a); //错误,数组不可以直接用一个数组赋值给另一个数组,只能一个一个元素赋值。
vector<int> a(n); //容器a中的元素全部初始为0
vector<int>a1(a); //a1是a的一个副本
三、存储方式
vector容器与数组都是其元素是以连续的方式存放的,但是数组的长度是固定的,vector对象可以在运行时高效地添加元素。这是vector容器与数组的一个很大的区别。
使用数组时数组长度是固定的,所以存储的数据不能超过其长度,若需要添加新的元素,只能重新定义一个数组,分配一个更大的内存空间来存储。也就是一个萝卜一个坑。。。
如:
int a[3]={0,1,2};
//若希望把0,1,2,3赋给a数组
int a[3]={0,1,2,3}; //系统会自动把3舍弃,数组a中存放的数据还是0,1,2
//所以只能重新定义一个更大的数组来存放
int a1[4]={0,1,2,3};
而vector容器可以实现快速的内存分配,其实际分配的容量要比当前的空间多一些。vector容器预留了这些额外的存储区,用于存放新添加的元素。
vector类提供了两个成员函数:capacity和reserve。
capacity操作获取在容器需要分配更多的存储空间之前能够存储的元素总数,与size操作不同,size指容器当前拥有的元素个数。
如:vector<int> ivec;
cout<<"ivec:size: "<<ivec.size()
<<" capacity: "<<ivec.capacity()<<endl;
for(vector<int>::size_type ix=0;ix!=24;++ix)
ivec.push_back(ix);
cout<<"ivec:size: "<<ivec.size()
<<" capacity: "<<ivec.capacity()<<endl;
以上程序输出结果:
ivec: size: 0 capacity: 0
ivec: size: 24 capacity: 32
由以上结果可知,空的容器size是0,而标准库显然将其capacity也设置为0。当程序员在vector中插入元素时,容器的size就是所添加的元素个数,而其capacity则必须至少等于size,但通常比size大。
vector容器可以动态添加元素
如:int i;
vector<int> a; //创建一个名为a的整形的没有元素的vector容器
while(cin>>i) //注意使这个循环结束可以在输入完毕后按ctrl+z然后回车,前提是你的输入法的切换建不是ctrl+z
a.push_back(i);//向a中动态添加元素并初始化直到输入错误为止
四、类型
vector实质上是一个类模版,由于这个原因,vector对象可以支持许多操作。而数组是由C语言继承过来的,C语言中没有类这个概念,所以数组是一个复合类型,并不像vector一样可以进行多种操作。
如:
vector<int> a;
a.size(); //返回a中元素的个数
a.push_back(2); //在a的末尾增加一个值为2的元素
a.begin(); //返回a中第一个元素的指针
a.end(); //返回指向a“末端元素的下一个”的指针
迭代器与指针
迭代器与指针一样可以分别历遍vector容器与数组的元素,使用自加(++)操作可以使其指向下一个元素,使用解引用(*)可以得到所指向元素的值.指针本质上是一种特殊的迭代器,指针是数组的迭代器。
一、操作方式
对于vector容器
下标操作:
for(vector<int>::size_type i=0;i!=a.size();++i)
a[i]=0;
相当于使用迭代器操作:
for(vector<int>::iterator iter=a.begin();iter!a.end();++iter)
*iter=0;
对应数组与指针:
const size_t arr_size=5;
int a[arr_sz]=(1,2,3,4,5}
for(int *pbegin=a,*pend=a+arr_sz;pbegin!pend;++pbegin)
*pbegin=0;
二、适用范围
迭代器是具有类似指针行为的class template。也就是重载了operator-> operator* operator++等操作符的类模板。
指针只能用于数组。而迭代器可以适用于所有容器。迭代器的设计就是为了数据结构的泛化。所以迭代器的适用范围更广。
指针除了用于访问数组的元素外还能指向单个对象,而迭代器只能用于访问容器内的元素。
后言:小的最近初学C++,若以上有概念有错,请各位大侠多多指教。。。