C++标准模板库(STL)中的是vector一种序列容器,它封装了能够存储任意类型(例如整数、字符串等)的动态大小数组。使用vector,你可以快速地在序列的末尾添加或移除元素,并且能够随机访问序列中的任何元素。下面我将详细介绍vector的特性、常用操作以及使用时的注意事项。
一、vector的特性
- 动态数组:vector内部通过动态分配的数组来存储元素,这意味着无需在编译时确定数组的大小,vector会根据需要自动调整存储空间的大小。
- 随机访问:vector支持通过索引快速访问元素(时间复杂度为O(1))。
- 自动管理内存:vector会自动管理其存储空间的分配和释放,降低了内存管理的复杂性。
- 方便进行大小调整:可以在vector的末尾添加或删除元素,调整其大小。
二、常用操作
1.创建和初始化:
std::vector<int> vec; // 创建一个空的vector
std::vector<int> vec2(10, 0); // 创建一个包含10个元素,每个元素都初始化为0的vector
注:如果声明了using namespace std,则std::前缀可以省略。
2.添加元素:
(1)在vector末尾添加一个元素 push_back(const value_type& val)
vec.push_back(1); // 在vec的末尾添加一个元素1
(2) 在指定位置前插入一个元素 insert(iterator position, const value_type& val)
vec.insert(vec.begin(), 1);//在开头位置插入元素1
// 假如我们想在索引为pos的位置插入元素4,
// vec.begin() 返回指向vector第一个元素的迭代器
// 在vec.begin()基础上加pos,就得到了指向第pos号位置(即第pos+1个位置)的迭代器
auto it = vec.begin() + pos;
// 使用insert函数在第pos号位置插入元素4
vec.insert(it, 4);
注意:insert操作的时间复杂度为O(n)
3.访问元素:
操作 | 函数接口 |
返回对第n 个元素的引用 | operator[](size_type n) |
返回对第n 个元素的引用,如果n 超出范围,则抛出out_of_range 异常 | at(size_type n) |
返回对第一个/最后一个元素的引用。 | front() / back() |
返回指向vector 首元素的指针 | data() |
// 使用operator[]访问第五个元素(索引从0开始)
std::cout << "使用operator[]访问第5个元素: " << vec[4] << std::endl;
// 使用at()访问第五个元素
std::cout << "使用at()访问第5个元素: " << vec.at(4) << std::endl;
4.迭代器遍历:
for(auto it = vec.begin(); it != vec.end(); ++it) {
std::cout << *it << " ";
}
5.删除元素:
操作 | 函数接口 |
移除vector 末尾的元素 | pop_back() |
删除指定位置的元素 | erase(iterator position) |
删除一个范围内的元素 | erase(iterator first, iterator last) |
清除所有元素 | clear() |
注:iterator为位置的迭代器,可以通过vec.begin()+pos获取
// erasing from vector
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> myvector;
// set some values (from 1 to 10)
for (int i=1; i<=10; i++) myvector.push_back(i);
// erase the 6th element
myvector.erase (myvector.begin()+5);
// erase the first 3 elements:
myvector.erase (myvector.begin(),myvector.begin()+3);
std::cout << "myvector contains:";
for (unsigned i=0; i<myvector.size(); ++i)
std::cout << ' ' << myvector[i];
std::cout << '\n';
return 0;
}
6.容器相关:
操作 | 函数接口 |
返回当前vector 中元素的数量 | size() |
返回vector 可能容纳的最大元素数量 | max_size() |
调整vector 的大小为n ,如果n 大于当前大小,则添加以val 为值的元素。 | resize(size_type n, value_type val = value_type()) |
返回当前为vector 分配的存储空间的大小 | capacity() |
检查vector 是否为空 | empty() |
请求改变vector 的容量至少为n | reserve(size_type n) |
// resizing vector
#include <iostream>
#include <vector>
int main ()
{
std::vector<int> myvector;
// set some initial content:
for (int i=1;i<10;i++) myvector.push_back(i);
myvector.resize(5);
myvector.resize(8,100);
myvector.resize(12);
std::cout << "myvector contains:";
for (int i=0;i<myvector.size();i++)
std::cout << ' ' << myvector[i];
std::cout << '\n';
return 0;
}
7.清空容器:
vec.clear()//清空容器
三、注意事项
- 性能考量:虽然可以动态增长,但是增加元素特别是在vector容量不足时会涉及到内存重新分配和元素拷贝,这可能是一个相对昂贵的操作。因此,在知道大致需要多少元素时,预先使用reverse()方法为vector分配足够的空间可以提高性能。at()
- 越界访问:使用下标操作符
[]
访问元素时,不会检查索引是否越界,而at()方法会进行越界检查并抛出异常。在关心安全性的上下文中,推荐使用at()。 - 迭代器失效:在进行插入或删除操作后,vector的迭代器可能会失效。特别是在插入元素时,如果发生了内存重新分配,之前的迭代器将全部失效。
参考资料: