Vector的使用笔记(1)
vector是使用的比较多的一种C++的STL类,之前没有系统地看过如何使用vector,导致使用的时候总觉得不好用。vector是为了取代直接定义的数组,可以进行下标越界检查,大小可以动态增长。大家总是建议使用vector,而不使用 Type array[size]。第一次用vector的时候,报错了,
vector<int> vInt;
vInt[0] = 1;
cout << vInt[0] << endl;
运行时报错,Segmetation fault。于是改了一下,
vInt.push_back(1);
这样就对了。后来便一直这样用。最近才发现自己太傻了,于是系统地看了一下vector的使用。
1、vector的构造函数
http://www.cplusplus.com/reference/stl/vector/vector/
explicit vector ( const Allocator& = Allocator() );
explicit vector ( size_type n, const T& value= T(), const Allocator& = Allocator() );
template <class InputIterator>
vector ( InputIterator first, InputIterator last, const Allocator& = Allocator() );
vector ( const vector<T,Allocator>& x );
还有参考示例,早应该看看了。如下,
// constructors used in the same order as described above:
//定义一个空的vector,同时也没有分配内存空间,这也是为什么vInt[0] =1;//赋值出现Segmentation fault的原因了。而使用push_back()表示追加一个元素,会重新分配空间,就没有出错了。
vector<int> first; // empty vector of ints
//定义一个有四个元素,且初始值都为100的vector。也可以不给出初始值,仅指定大小。
vector<int> second (4,100); // four ints with value 100
//使用vector的迭代器初始化,得到源vector的一段。
vector<int> third (second.begin(),second.end()); // iterating through second
//使用一个vector初始化
vector<int> fourth (third); // a copy of third
// the iterator constructor can also be used to construct from arrays:
int myints[] = {16,2,77,29};
//使用array的起始地址和终止地址初始化
vector<int> fifth (myints, myints + sizeof(myints) / sizeof(int) );
2、vector元素的访问和赋值
对单个元素
operator[],下标操作运算符,与访问数组array一致,它不检查下标是否越界。
at(size_type n),进行了下标检查,返回引用,或是const引用,可以用来访问和赋值。大家推荐用at()而不是[]访问向量。当下标越界时,使用[]报错segmetation fault,使用at()报错 out of range,错误信息更明确。
当[]或at()访问的元素在vector中时,也就可以用来赋值。
顺序遍历
for(unsigned int i=0;i<vInt.size();i++)
{
cout << vInt[i] <<" ";
}
vector的size()函数返回vector的元素个数,为无符号数,所以定义unsigned int i;这种定义存在一个问题,当从最后一个元素访问到第一个元素时,for(unsigned int i=vInt.size()-1;i>=0;i--)则会出现访问越界的问题,因为i是无符号数,i>=0是永远满足的条件。
STL中的容器的遍历都有一种叫做迭代器的机制。对于vector,可以用迭代器来遍历。如下,
for(vector<int>::iterator it = vi.begin() ; it !=vi.end() ; it++) ///第二种调用方法
{
cout << *it << " " ;
}
3、vector的动态增长
vector的一个好处是可以动态增长,虽然是以性能为代价的。如果需要追加元素,push_back或pop_back,vector的size会随之改变。
4、swap()函数
swap还是很有用的,比如前面一篇vector内存释放里提到的,用来释放vector的占用的内存。比如多项式乘法的函数,
void polyMultiAssign(vector<double> &ak,vector<double> &bk)
{
//申请一个大小为na+nb-1的vector,存放结果
vector<double> ck(ak.size()+bk.size()-1);
//。。。运算
//将结果保存到ak中,
ak.swap(ck);
//将结果保存在ak中,ck的内存在函数结束的时候释放
}
4、vecrtor的allocator
vector的构造函数中可以传入allocator的参数,一般使用默认的allocator。
在有的地方提到了这样一个例子,
vector<int> vd;
//使用 vector的allocator申请空间,
int *p = vd.get_allocator().allocate(10);
p[0] = 1;
...
// 使用vector的allocator释放空间,
vd.get_allocator().deallocate(p,10);
这里使用的是vector的allocator,而不是vector本身。这个与使用new/delete申请一个数组有什么区别呢?好像是没有区别的。
int *p = new int[10];
delete [] p;
希望以后对vector能理解的更好,更清楚。