C++ std::vector
标准库类型
std::vector
是 C++ 标准库中动态数组的实现,支持自动扩容、随机访问和高效的元素操作。

1. 头文件与基本定义
-
头文件 :需包含
<vector>
。 -
命名空间 :属于
std
命名空间。 -
基本声明 :
cpp#include <vector> using namespace std; // 或显式使用 std::vector
2. 初始化与构造
vector
支持多种初始化方式:
cpp
vector<int> v1; // 默认构造:空 vector
vector<int> v2(5, 100); // 含 5 个元素,每个值为 100
vector<int> v3 = {1, 2, 3}; // 列表初始化(C++11 起)
vector<int> v4(v3); // 拷贝构造(v4 与 v3 相同)
vector<int> v5(v3.begin(), v3.end()); // 通过迭代器范围构造
3. 常用操作
(1) 元素访问
-
下标访问:
cppint a = v3[0]; // 访问第一个元素(不检查越界) int b = v3.at(1); // 访问第二个元素(越界抛出 std::out_of_range) int c = v3.front(); // 首元素(等价于 v3[0]) int d = v3.back(); // 尾元素(等价于 v3[v3.size()-1])
-
范围检查:
cppif (!v3.empty()) { // 确保 vector 非空 cout << v3[0]; }
(2) 添加元素
-
尾部插入:
cppv1.push_back(30); // 添加元素 30 到尾部 v1.emplace_back(40); // 更高效(C++11,直接在容器内构造对象)
-
任意位置插入:
cppauto it = v3.begin() + 2; v3.insert(it, 99); // 在索引 2 处插入 99 → {1, 2, 99, 3, 4, 5}
(3) 删除元素
-
尾部删除:
cppv3.pop_back(); // 删除最后一个元素 → {1, 2, 99, 3, 4}
-
任意位置删除:
cppauto it = v3.begin() + 2; v3.erase(it); // 删除索引 2 处的元素 → {1, 2, 3, 4} v3.erase(v3.begin(), v3.begin() + 2); // 删除前两个元素 → {3, 4}
-
清空 vector:
cppv3.clear(); // 清空所有元素,size 变为 0
4. 容量管理
(1) 容量与大小
int size = v3.size(); // 元素数量
bool isEmpty = v3.empty();// 是否为空
int capacity = v3.capacity(); // 当前分配的存储容量(>= size)
(2) 调整容量
-
预分配内存(避免频繁扩容):
v3.reserve(100); // 预分配容量为 100,size 不变
-
调整元素数量:
cppv3.resize(10); // 若 size < 10,填充默认值(int 为 0) v3.resize(5); // 若 size > 5,截断后 5 个元素 v3.resize(8, 99); // 填充 99 到新增位置
5. 迭代器与范围遍历
(1) 迭代器操作
cpp
// 正向迭代器
for (auto it = v3.begin(); it != v3.end(); ++it) {
cout << *it << " ";
}
// 反向迭代器
for (auto rit = v3.rbegin(); rit != v3.rend(); ++rit) {
cout << *rit << " ";
}
// C++11 范围 for 循环
for (int num : v3) {
cout << num << " ";
}
(2) 迭代器失效问题
-
插入/删除元素可能导致迭代器失效 :
cppauto it = v3.begin() + 1; v3.push_back(10); // 可能导致迭代器失效(若触发扩容) // 此时使用 it 是未定义行为!

6. 性能与优化
(1) 动态扩容机制
- 扩容策略 :当
size
超过capacity
时,vector 会分配新内存(通常容量翻倍),并将旧元素拷贝到新内存。 - 时间复杂度 :
- 尾部插入(
push_back
):均摊 O(1)。 - 中间插入/删除:O(n)。
- 尾部插入(
(2) 高效操作建议
-
批量插入:
cppvector<int> newData = {10, 20, 30}; v3.insert(v3.end(), newData.begin(), newData.end());
-
移动语义(C++11):
cppvector<string> v6; string str = "hello"; v6.push_back(std::move(str)); // 移动而非拷贝,str 变为空
7. 算法与 vector
结合
cpp
#include <algorithm>
vector<int> nums = {3, 1, 4, 1, 5};
sort(nums.begin(), nums.end()); // 排序:1, 1, 3, 4, 5
auto it = find(nums.begin(), nums.end(), 4); // 查找元素 4 的位置
reverse(nums.begin(), nums.end()); // 反转:5, 4, 3, 1, 1
8**. 与数组的对比**
特性 | std::vector |
原生数组 (int[] ) |
---|---|---|
内存管理 | 自动扩容和释放 | 手动管理 |
大小 | 动态调整 | 固定大小 |
访问效率 | 相同随机访问复杂度(O(1)) | 相同 |
安全性 | 越界检查(at() 方法) |
无检查,越界导致未定义行为 |
9. 注意事项
- 越界访问 :
operator[]
不检查越界,at()
会抛出std::out_of_range
。 - 迭代器失效:插入/删除操作可能导致迭代器、指针或引用失效。
vector<bool>
特化:避免使用vector<bool>
,其行为类似压缩位数组,与标准容器不一致。- 避免频繁插入/删除中间元素 :优先使用
std::list
或std::deque
。 - 预分配内存 :已知元素数量时,使用
reserve
减少扩容次数。 - 元素类型要求:需支持拷贝或移动构造函数(如自定义类)。
10**. 综合示例**
cpp
#include <iostream>
#include <vector>
#include <algorithm> // 用于 sort
using namespace std;
int main() {
vector<int> nums = {3, 1, 4, 1, 5, 9, 2, 6};
// 排序
sort(nums.begin(), nums.end()); // 1, 1, 2, 3, 4, 5, 6, 9
// 去重
auto last = unique(nums.begin(), nums.end());
nums.erase(last, nums.end()); // 1, 2, 3, 4, 5, 6, 9
// 遍历输出
for (int num : nums) {
cout << num << " ";
}
return 0;
}
11. 总结
核心优势 | 说明 |
---|---|
动态大小 | 无需预先指定容量,自动调整 |
随机访问 | 支持 O(1) 时间访问任意元素 |
内存安全 | 自动管理内存,避免泄漏和越界 |
与算法库无缝协作 | 支持标准库算法(如 sort , find ) |