vector 是 C++ 标准库(STL)提供的动态数组容器,本质是对「原生动态数组(new[]/delete[])」的封装,核心优势是 自动管理内存(无需手动 new/delete)、支持动态扩容、提供丰富的成员函数,比原生动态数组更安全、更易用。
一、vector 核心优势(为什么用 vector?)
对比之前的原生动态数组,vector 解决了三大痛点:
- 无需手动管理内存(自动分配 / 扩容 / 释放,避免内存泄漏);
- 内置
size()成员函数,直接获取数组长度(无需手动记录n); - 支持动态添加 / 删除元素(
push_back()/pop_back()),长度可灵活调整; - 兼容原生数组的访问方式(下标 / 指针),学习成本低。
二、vector 基础用法(四步走)
步骤 1:包含头文件 + 命名空间
vector 定义在 <vector> 头文件中,需提前包含:
#include <iostream>
#include <vector> // 必须包含 vector 头文件
using namespace std; // 简化命名,避免写 std::vector
步骤 2:创建 vector(初始化方式)
vector 是模板类,创建时需指定元素类型(如 int、char),支持多种初始化方式,按需选择:
| 初始化方式 | 语法示例 | 说明 |
|---|---|---|
| 空 vector(默认) | vector<int> vec; | 创建空的 int 类型 vector,初始长度为 0 |
| 指定长度(默认初始化) | vector<int> vec(5); | 长度为 5,元素默认值为 0(int 类型) |
| 指定长度 + 初始值 | vector<int> vec(5, 10); | 长度为 5,所有元素初始化为 10([10,10,10,10,10]) |
| 列表初始化(C++11+) | vector<int> vec = {1,2,3,4,5}; | 直接用列表赋值,长度自动为 5 |
| 拷贝初始化 | vector<int> vec2(vec1); | 用 vec1 的元素拷贝创建 vec2(完全独立) |
示例:
vector<int> vec1; // 空 vector(size=0)
vector<int> vec2(3); // [0, 0, 0](size=3)
vector<int> vec3(3, 6); // [6, 6, 6](size=3)
vector<int> vec4 = {2,4,6,8}; // [2,4,6,8](size=4)
vector<int> vec5(vec4); // 拷贝 vec4 → [2,4,6,8]
步骤 3:vector 核心操作(赋值 / 访问 / 增删)
vector 支持「下标访问」和「成员函数访问」,以下是最常用的操作:
1. 赋值与访问元素
- 下标访问:和原生数组一致(
vec[i]),但不检查下标越界(越界会崩溃); at(i)访问:检查下标越界(越界会抛异常),更安全;- 遍历方式:循环下标、迭代器(推荐)、范围 for(C++11+,最简洁)。
示例:
vector<int> vec = {10,20,30};
// 1. 赋值(下标)
vec[0] = 100; // vec 变为 [100,20,30]
vec.at(1) = 200; // vec 变为 [100,200,30](安全访问)
// 2. 遍历方式 1:循环下标(适合需要索引的场景)
cout << "遍历方式 1(下标):";
for (int i = 0; i < vec.size(); i++) {
cout << vec[i] << " "; // 输出:100 200 30
}
cout << endl;
// 3. 遍历方式 2:范围 for(C++11+,最简洁,无需索引)
cout << "遍历方式 2(范围 for):";
for (int x : vec) {
cout << x << " "; // 输出:100 200 30
}
cout << endl;
// 4. 遍历方式 3:迭代器(STL 标准方式,兼容所有容器)
cout << "遍历方式 3(迭代器):";
for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) {
cout << *it << " "; // *it 访问迭代器指向的元素
}
cout << endl;
2. 动态增删元素
vector 最强大的功能是动态调整长度,核心函数:
push_back(x):在数组末尾添加元素x(自动扩容);pop_back():删除数组末尾元素(长度减 1,不释放内存);clear():清空所有元素(长度变为 0,不释放内存);empty():判断是否为空(size()==0等价,但更高效)。
示例:
vector<int> vec;
// 添加元素(push_back)
vec.push_back(1); // [1](size=1)
vec.push_back(2); // [1,2](size=2)
vec.push_back(3); // [1,2,3](size=3)
// 删除末尾元素(pop_back)
vec.pop_back(); // [1,2](size=2)
// 判断是否为空
if (!vec.empty()) {
cout << "当前 vector:";
for (int x : vec) cout << x << " "; // 输出:1 2
}
// 清空元素
vec.clear(); // 空 vector(size=0)
cout << "\n清空后 size:" << vec.size(); // 输出:0
3. 获取长度与容量
size():返回当前元素个数(实际存储的元素数);capacity():返回当前分配的内存容量(能容纳的最大元素数,扩容时会翻倍)。
示例:
vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);
cout << "size:" << vec.size(); // 3(实际有 3 个元素)
cout << "capacity:" << vec.capacity(); // 通常是 4(不同编译器可能不同,扩容策略是翻倍)
步骤 4:释放 vector 内存(可选)
vector 会在生命周期结束时自动释放内存(比如函数返回、main 结束),无需手动释放,避免了原生动态数组的内存泄漏问题。
若需手动释放内存(比如 vector 占用过大,想提前回收),可使用「swap 技巧」:
vector<int> vec(1000, 10); // 占用较大内存
vec.swap(vector<int>()); // 与空 vector 交换,原内存被释放
cout << "size:" << vec.size(); // 0
cout << "capacity:" << vec.capacity(); // 0
三、vector 与原生动态数组对比(关键区别)
| 特性 | vector(容器) | 原生动态数组(new[]) |
|---|---|---|
| 内存管理 | 自动分配 / 扩容 / 释放(无泄漏风险) | 手动 new[]/delete[](易漏释放) |
| 长度获取 | size() 直接获取(安全) | 需手动记录 n(易出错) |
| 动态调整长度 | push_back()/pop_back() 直接支持 | 需重新分配内存 + 拷贝元素(复杂) |
| 下标越界检查 | at(i) 支持(安全),[] 不支持 | 不支持(越界直接崩溃) |
| 易用性 | 高(成员函数丰富) | 低(需手动处理所有细节) |
结论:日常开发中,优先用 vector 替代原生动态数组,除非有特殊底层优化需求。
四、实战示例:用 vector 实现「找最大 / 最小值」
结合你之前的需求,用 vector 重写找最大 / 最小值的程序,对比原生动态数组更简洁安全:
#include <iostream>
#include <vector>
using namespace std;
// 函数参数:vector<int>&(引用传递,避免拷贝,效率高)
void findMaxMin(const vector<int>& vec) {
if (vec.empty()) { // 边界处理:空 vector
cout << "vector 为空!" << endl;
return;
}
int max_val = vec[0];
int min_val = vec[0];
// 范围 for 遍历(简洁)
for (int x : vec) {
if (x > max_val) max_val = x;
if (x < min_val) min_val = x;
}
cout << "max = " << max_val << endl;
cout << "min = " << min_val << endl;
}
int main() {
int n;
cout << "请输入元素个数:";
cin >> n;
vector<int> vec(n); // 创建长度为 n 的 vector
cout << "请输入 " << n << " 个整数:";
for (int i = 0; i < n; i++) {
cin >> vec[i]; // 下标赋值
}
findMaxMin(vec); // 直接传入 vector(引用传递)
// 无需手动释放内存(vector 生命周期结束自动释放)
return 0;
}
运行效果:
plaintext
请输入元素个数:5
请输入 5 个整数:3 1 4 2 5
max = 5
min = 1
五、vector 常见误区与避坑
1. 下标越界访问
- 错误:
vector<int> vec(3); vec[5] = 10;(下标 5 超出 size=3); - 后果:程序崩溃(未定义行为);
- 解决:用
at(i)访问(越界会抛异常,便于调试),或访问前检查i < vec.size()。
2. 混淆 size() 和 capacity()
size()是实际元素个数,capacity()是当前内存能容纳的最大元素数;- 例如:
vec.push_back(1)后,size=1,capacity可能是 2(编译器默认扩容策略); - 误区:认为
capacity()等于size(),导致误判内存占用。
3. 频繁 push_back() 导致扩容开销
vector扩容时会:分配新内存 → 拷贝旧元素 → 释放旧内存(有性能开销);- 优化:提前用
reserve(n)预留容量(避免频繁扩容),比如已知要存 1000 个元素:vector<int> vec; vec.reserve(1000); // 提前预留 1000 个元素的容量 for (int i = 0; i < 1000; i++) { vec.push_back(i); // 无扩容开销,效率更高 }
总结
vector 是 C++ 最常用的容器,核心是「自动内存管理 + 动态扩容 + 易用性」,基础用法可总结为:
- 包含
<vector>头文件; - 用合适的方式初始化
vector; - 用
[]/at()访问元素,用push_back()/pop_back()增删元素; - 用
size()获取长度,无需手动释放内存。
1160

被折叠的 条评论
为什么被折叠?



