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能理解的更好,更清楚。

原文地址:https://www.cnblogs.com/Frandy/p/Vector_Using_1.html