头文件:#include
vector的数据安排和操作方式与c++内建的array非常相似。不同之处就是array是静态分配内存空间,需要在定义array的时候就给定array的大小。vector是动态分配内存空间的,随着新元素的加入,系统会自动进行内存的扩容。
vector维护的是一个连续的线性空间。那么当新的元素加入时,如果内存不够用了,系统会怎么处理?
首先,vector的内存是连续的线性空间,所以当内存不够用时只能重新分配更大的连续内存,然后把之前的数据复制到新的内存中,释放之前的内存,最后继续push新的数据。
那么,这个内存空间怎么计算呢?怎么知道扩容时应该分配多大的内存?
显然,如果扩容较小,则会导致扩容次数增多,复制操作变多,影响效率。但是如果扩容太大,又会导致资源浪费。权衡两者,目前的扩容方法如下:
1. 初始时,vector的capacity为0
2. 插入一个元素时,vector的capacity为1
3. 后面继续插入元素时不同编译器的扩容方式不一致,
VS2015中以1.5倍扩容,GCC以2倍扩容。
以VS2015为例,写代码具体看看:
int main()
{
vector v;
for (int i = 0; i < 16; i++)
{
cout << "the size is: " << v.size() << endl;
cout << "the capacity is: " << v.capacity() << endl;
v.push_back(i);
}
return 0;
}
测试结果如下:
建议有时间和兴趣的同学读一下STL源码,个人感觉写的确实很好,对写代码提升很大。由于是几年前看过的,现在忘得差不多了,此处就先省略,直接讲下vector的用法:
1. vector的构造
vector( const Allocator& = Allocator() );
vector( size_type n,constT& value = T(), const Allocator& = Allocator() );
template
vector ( InputIterator first, InputIterator last, const Allocator& = Allocator() );
vector ( const vector& x );
具体用法:
vector v1; // size=0, 无数据
vector v2(5); // 数据为{0,0,0,0,0}
vector v3(5, 10); // 数据为{10,10,10,10,10}
int arr[5] = { 1,2,3,4,5 };
vector v4(arr, arr+5); // 数据为{1,2,3,4,5}
vector v5(v4.begin(), v4.end()-1); // 数据为{1,2,3,4}
vector v6(v5); // 数据为{1,2,3,4}
vector v7 = v6; // 数据为{1,2,3,4}
2. vector的assign函数
函数原型是:
1:void assign(const_iterator first,const_iterator last);
2:void assign(size_type n,const T& x = T());
第一个相当于个拷贝函数,把first到last的值赋值给调用者;
第二个把n个x赋值给调用者;
int arr[5] = { 1,2,3,4,5 };
vector v1(arr, arr + 5);
vector v2;
v2.assign(v1.begin(), v1.begin() + 2); // v2结果: {1,2}
vector v3;
v3.assign(6,8); // v3结果: {8,8,8,8,8}
3. vector的一些查询操作
int arr[5] = { 1,2,3,4,5 };
vector v(arr, arr+5);
bool empty = v.empty(); // vector是否为空,是返回true,否则为false
int size = v.size(); // vector的大小,返回vector实际填充数据的大小
int cap = v.capacity(); // vector内存大小,返回vector实际占用内存的大小
4. vector的push_back和pop_back函数
vector v(2,6); // v为{6,6}
v.push_back(3); // v为{6,6,3}
v.pop_back(); // v为{6,6}
push_back的用法很简单,就是在vector的最后插入一个值。 返回值为void。
5. vector的insert函数
insert() 函数有以下两种用法:
1、 iterator insert(const_iterator _Where, const bool& _Val):
在指定位置loc前插入值为val的元素,返回指向这个元素的迭代器。2、 iterator insert(const_iterator _Where, size_type _Count, const bool& _Val)
在指定位置loc前插入count个值为val的元素
vector v;
v.push_back(3); // v为:{3}
vector::iterator it1 = v.insert(v.begin(),5); // v为:{5,3}
vector::iterator it2 = v.insert(v.end(), 3, 1); // v为:{5,3,1,1,1}
int a = *it1; // 运行到此处程序会崩溃,后面讲为什么
int b = *it2;
6. vector的begin和end函数
vector v;
v.push_back(3);
vector::iterator begin = v.begin(); // 返回vector的第一个迭代器
int a = *begin; // a = 3
vector::iterator end = v.end();
int b = *end; // 程序崩溃,因为end指向未知内存
7. vector的clear和erase函数
earse参数为iterator ,删除vector中这个迭代器指向的数值。
clear,清除vector中所有数据。释放内存。
vector v;
v.push_back(1);
v.push_back(2);
v.push_back(3); // v是{1,2,3}
vector::iterator begin = v.begin();
v.erase(begin+1); // v是{1,3}
v.clear(); // v是{}
8. vector的front和back函数
front/back函数和前面的begin和end函数类似,只是返回值类型不同。begin/end返回值为itorator,front/back返回值为reference.
vector v1(arr, arr + 5);
int a = v1.front(); // a = 1
int b = v1.back(); // b = 5
9. vector的at函数
at函数和vector[]类似,但是比vector[]更安全,因为他有边界判断。
int arr[5] = { 1,2,3,4,5 };
vector v1(arr, arr + 5);
int a = v1.at(1); // a = 2
int b = v1.at(7); // 超过边界,抛出异常。
int c = v1[7]; // 超过边界,不抛出异常,所以很危险。
10. vector的reserve和resize函数
int arr[5] = { 1,2,3,4,5 };
vector v1(arr, arr + 5);
cout << "size is: " << v1.size() << " , capacity: " << v1.capacity() << endl;
v1.reserve(10);
cout << "size is: " << v1.size() << " , capacity: " << v1.capacity() << endl;
v1.resize(20);
cout << "size is: " << v1.size() << " , capacity: " << v1.capacity() << endl;
运行结果如下:
vector的迭代器是一个普通指针。支持it++,it--等操作。
vecor的insert会造成所有迭代器失效,因为verctor的记忆体重新配置。
vector在尾部进行插入和删除操作,有front和back函数分别用于取头、尾数据。
erase函数用来清除部分数据,清除之后返回下一个元素的指针。
insert函数用来在某位置插入指定个数的元素,eg: insert(iterator it,int len,int num);
二维vector的push_back:首先定义一个一维vector,给一维vector中push数据,然后把一维vector push到二维vector中。
vector清除的三种方法:
vector
1、用clear,vec.clear(); 此方法清除数据但不释放空间
2、循环使用erase,效果同上
3、swap,vector