以下是 C++ 中 std::vector
的详细使用指南,涵盖初始化、常用操作、性能优化及注意事项:
1. 基本概念
定义:
vector
是动态数组,可自动管理内存,支持随机访问(O(1) 时间复杂度)。头文件:
#include <vector>
特点:
元素在内存中连续存储。
尾部插入/删除高效(均摊 O(1)),中间插入/删除效率低(O(n))。
可动态扩展容量(通过
push_back
或resize
)。
2. 初始化与构造
(1) 空容器
std::vector<int> vec; // 空vector
(2) 指定大小和初始值
std::vector<int> vec1(5); // 5个int,默认初始化为0 std::vector<int> vec2(5, 42); // 5个int,初始化为42
(3) 列表初始化(C++11+)
std::vector<int> vec = {1, 2, 3, 4, 5}; std::vector<std::string> names {"Alice", "Bob"};
(4) 从其他容器构造
std::vector<int> vec3(vec2.begin(), vec2.end()); // 复制vec2 std::vector<int> vec4(vec3); // 拷贝构造
3. 元素访问
(1) 下标访问
vec[0] = 10; // 不检查越界(类似数组) int val = vec.at(2); // 越界抛出std::out_of_range异常
(2) 首尾元素
int first = vec.front(); // 首元素 int last = vec.back(); // 尾元素
(3) 迭代器遍历
for (auto it = vec.begin(); it != vec.end(); ++it) { std::cout << *it << " "; } // 范围for循环(C++11+) for (const auto& num : vec) { std::cout << num << " "; }
4. 添加/删除元素
(1) 尾部操作
vec.push_back(6); // 尾部插入元素 vec.emplace_back(7); // 更高效(C++11+,避免临时对象拷贝) vec.pop_back(); // 删除尾部元素(不返回被删元素)
(2) 任意位置插入/删除
auto it = vec.begin() + 2; vec.insert(it, 99); // 在位置2插入99 vec.erase(it); // 删除位置2的元素
(3) 清空容器
vec.clear(); // 清空所有元素,容量不变
5. 容量管理
(1) 查询容量
int size = vec.size(); // 当前元素数量 bool isEmpty = vec.empty(); // 是否为空 int cap = vec.capacity(); // 当前分配的内存容量
(2) 调整容量
vec.reserve(100); // 预分配容量(避免多次扩容) vec.resize(10); // 调整元素数量,多出的元素默认初始化 vec.resize(15, 42); // 调整到15个元素,新增元素初始化为42 vec.shrink_to_fit(); // 释放未使用的内存(C++11+)
6. 高级操作
(1) 与算法库结合
#include <algorithm> std::sort(vec.begin(), vec.end()); // 排序 auto it = std::find(vec.begin(), vec.end(), 42); // 查找元素 std::reverse(vec.begin(), vec.end()); // 反转
(2) 交换容器
std::vector<int> vecA {1, 2, 3}; std::vector<int> vecB {4, 5}; vecA.swap(vecB); // 高效交换内容(O(1) 时间复杂度)
(3) 移动语义(C++11+)
std::vector<int> vecX = std::move(vecY); // 移动构造,vecY变为空
(4) 删除满足某个条件的元素:
std::vector<int> nums = {0, 1, 2, 3, 4, 5}; // 删除所有偶数 nums.erase(std::remove_if(nums.begin(), nums.end(), [](int x) { return x % 2 == 0; }), nums.end()); // nums = {1, 3, 5}
7. 性能优化与陷阱
(1) 预分配内存
std::vector<int> vec; vec.reserve(1000); // 避免频繁扩容(扩容会导致数据拷贝)
(2) 避免无效操作
迭代器失效:在插入/删除元素后,原有迭代器可能失效。
auto it = vec.begin(); vec.push_back(10); // 可能导致it失效(若触发扩容)
(3) 元素类型要求
元素类型需支持拷贝构造或移动构造(如类对象)。
8. 示例代码
#include <vector> #include <iostream> #include <algorithm> int main() { std::vector<int> nums = {3, 1, 4, 1, 5}; nums.reserve(10); // 预分配容量 nums.push_back(9); nums.emplace_back(2); // 直接构造,避免拷贝 std::sort(nums.begin(), nums.end()); // 删除所有值为1的元素 nums.erase(std::remove(nums.begin(), nums.end(), 1), nums.end()); // 输出结果 for (int num : nums) { std::cout << num << " "; // 输出:2 3 4 5 9 } return 0; }
9. 适用场景
需要频繁随机访问元素。
尾部插入/删除操作多,中间操作少。
不确定元素数量,需动态扩展。
通过掌握这些方法,你可以高效利用 std::vector
解决大多数动态数组需求。实际开发中,优先选择 vector
而非原生数组,除非有特殊性能要求。
系统当前共有 442 篇文章