1. 引言
1.1 vector
是什么?
在 C++
标准模板库(STL
)中,vector
是最常用也最经典的容器之一。它本质上是一个可以动态扩展的一维数组,提供了灵活的内存管理和高效的访问性能。
与原生数组(int arr[100]
)相比,vector
更加安全且易于使用。它支持自动扩容、范围检查(通过 at()
方法),并能与 STL
中的算法(如 sort
、find
、for_each
等)无缝协作,使得开发效率和代码可读性大大提升。
1.2 vector
的优势
-
动态扩容:无需提前预估大小,自动处理内存管理。
-
高效随机访问:和数组一样支持常数时间的下标访问。
-
与
STL
算法协同良好 :标准库算法大多数都能直接用于vector
。 -
语法简洁:易于声明、初始化、遍历、操作。
1.3 vector
的适用场景
-
需要频繁添加元素(尤其是尾部添加)的情况;
-
数据大小不固定,或在运行时确定;
-
需要快速访问元素(通过索引)的程序逻辑;
-
临时存储、缓存、数据采集等功能模块;
-
替代传统
C
风格数组,提升代码健壮性和可维护性。
2.vector
的常见构造方式
C++
提供了多种方式来构造 vector
,以适应不同的使用场景。在使用vector
之前要加入头文件#include<vector>
2.1 默认构造
创建一个空的 vector
,不包含任何元素。
vector<int> v1;
2.2 初始值和大小构造
创建一个包含 n
个元素的 vector
,所有元素初始化为指定的值。
vector<int> v2(10, 5);//创建一个包含 10 个元素,每个元素初始化为 5 的 vector
输出内容:

2.3 使用迭代器范围构造
可以用另一个容器或数组的范围来初始化 vector
。
vector<int> origin = { 1, 2, 3, 4, 5 };
vector<int> v3(origin.begin(), origin.end()); // 拷贝 origin 所有元素
2.4 拷贝构造
使用另一个 vector
创建一个副本。
vector<int> v4(v3); 或vector<int> v4 = v3;// 拷贝构造,v4 和 v3 拥有相同内容
2.5 移动构造
C++11
引入了移动语义,这使得 vector
可以通过移动构造函数将资源从一个已有的 vector
转移到新的 vector
中,而不需要进行元素的深拷贝。
vector<int> origin = { 1,2,3 };
vector<int> v5 = move(origin);// 使用移动构造函数
这些构造方式基本覆盖了开发中大多数场景。推荐使用 带容量初始化 或 迭代器构造 来保证代码的性能和可读性。
3.vector
常用成员函数
vector
提供了丰富的成员函数来支持增删查改和容量管理。掌握这些函数的使用是高效编程的关键。
3.1 增加元素
push_back()
作用:在末尾添加一个元素,拷贝构造或移动构造。
cpp
vector<int> v1;
//在末尾添加元素
v1.push_back(10);
v1.push_back(20);
v1.push_back(30);
v1.push_back(40);
v1.push_back(50);
输出内容:

emplace_back()
作用:在末尾原地构造一个元素,效率高于 push_back()
,避免拷贝或移动。
cpp
vector<int> v;
v.emplace_back(10);//原地构造10
输出内容:

insert()
作用:在指定位置插入一个或多个元素。
cpp
vector<int> v = { 1,2,5 };
v.insert(v.begin() + 2, 3);// 在索引 2 插入 3,结果:1 2 3 5
输出内容:

3.2 删除元素
pop_back()
作用:删除最后一个元素。
cpp
vector<int> v = { 1,2,3,4,5 };
v.pop_back();
输出内容:

erase()
作用:删除指定位置的元素或范围。
cpp
vector<int> v = { 1,2,3,4,5 };
v.erase(v.begin()); // 删除第一个元素
输出内容:

cpp
vector<int> v = { 1,2,3,4,5 };
v.erase(v.begin(),v.begin()+2);// 删除前两个元素
输出内容:

clear()
作用:清空所有元素。
cpp
vector<int> v = { 1,2,3,4,5 };
v.clear();
输出内容:

3.3 访问元素
operator[]
vector
提供了重载的 operator[]
来通过下标访问元素。
cpp
vector<int> v = { 1,2,3,4,5 };
cout << v[2] << endl; //访问容器第 3 个元素 3
输出内容:

如果使用 operator[]
访问越界的元素,它不会抛出异常,而是会导致未定义行为(可能返回垃圾值或者引发崩溃)。
at()
at()
函数与operator[]
类似,但它提供了边界检查,如果索引越界,将抛出std::out_of_range
异常。
cpp
vector<int> v = { 1,2,3,4,5 };
cout << v.at(2) << endl;//输出30
try {
cout << v.at(5) << endl; //抛出std::out_of_range
}catch (const out_of_range& e) {
cout << "超出最大访问范围!" << e.what() << endl;
}
输出内容:

front()
和 back()
front()
: 返回 vector
中的第一个元素。
back()
: 返回 vector
中的最后一个元素。
cpp
vector<int> v = { 1,2,3,4,5 };
cout << v.front() << endl; // 1
cout << v.back() << endl; // 5
输出内容:

3.4 容量与大小
size()
作用:返回当前元素个数。
cpp
vector<int> v = { 1,2,3,4,5 };
cout << v.size() << endl;// 5
输出内容:

capacity()
作用:当前分配的容量,不一定等于 size()
,用于优化性能。
cpp
vector<int> v = { 1,2,3,4,5 };
cout << v.capacity() << endl;
输出内容:

empty()
作用:容器是否为空。
cpp
vector<int> v = { 1,2,3,4,5 };
if (v.empty()) {
cout << "vector v为空" << endl;
}else {
cout << "vector v不为空" << endl;
}
输出内容:

resize(n)
作用:改变大小,多则填默认值,少则截断。
cpp
vector<int> v = { 1,2,3,4,5 };
v.resize(10);// 调整为10个元素
输出内容:
v.resize(3);// 调整为3个元素
输出内容:

reserve(n)
作用:预分配空间,避免频繁扩容。
cpp
v.reserve(100);// 提前分配空间
cout << v.capacity() << endl; //打印现在容量 100
输出内容:

shrink_to_fit()
作用:请求释放未使用的内存(可能无效果,依赖实现)。
cpp
vector<int> v;
v.reserve(100);// 提前分配空间
v.push_back(10);
v.push_back(10);
v.push_back(10);
v.push_back(10);
v.shrink_to_fit(); //释放未使用的内存
cout << v.capacity() << endl; //打印现在容量 4
输出内容:

4.vector
的底层实现与性能分析
C++
中的 vector
是一种封装了动态数组的容器,其底层实现对性能优化做得非常优秀。本节将从底层结构、内存管理与操作复杂度三个方面进行剖析。
4.1 动态扩容机制
在 std::vector
的实现中,动态扩容(Dynamic Resizing) 是其核心机制之一。它允许容器在运行时自动调整存储空间,以适应元素的动态增长。然而,不同的 C++
标准库实现(如 GCC、Clang、MSVC)可能采用不同的扩容策略,这对性能有直接影响。
动态扩容的基本原理
当 vector
的 size()
即将超过 capacity()
时,容器会执行以下步骤:
1. 分配新内存:申请一块更大的连续内存(通常是原容量的 1.5 倍或 2 倍)。
2. 迁移数据:将旧元素拷贝(或移动)到新内存。
3. 释放旧内存:销毁旧存储空间,完成扩容。
关键点:
扩容策略 :标准未规定具体增长因子,但要求 push_back
的均摊时间复杂度为 O(1)
。
迭代器失效:扩容后,所有迭代器、指针、引用均失效(因内存地址变更)。
常见实现策略对比
不同编译器的 vector
扩容策略可能不同:
编译器/库 | 典型增长因子 | 示例扩容序列(初始容量=1) | 实现特点 |
---|---|---|---|
GCC (libstdc++) | 2× | 1 → 2 → 4 → 8 → 16 → ... | 严格翻倍,适合快速扩容 |
MSVC (STL) | ~1.5× | 1 → 2 → 3 → 4 → 6 → 9 → 13 → ... | 平衡内存浪费与扩容频率 |
Clang (libc++) | ~1.5× | 1 → 2 → 4 → 8 → 16 → ... | 类似 GCC |
以MSVC代码为例
cpp
vector<int> v;
for (int i = 0; i < 10; ++i) {
v.push_back(i);
cout << "size:" << v.size() << ", capacity:" << v.capacity() << endl;
}
输出内容:

4.2 性能分析
时间复杂度
均摊 O(1)
:虽然单次扩容是 O(N)
,但经过均摊分析(Amortized Analysis),push_back
的均摊成本为 O(1)
。
最坏情况 :插入 N
个元素的总成本为 O(N)
,因每次扩容的拷贝次数总和收敛于 2N
(如 2× 扩容)。
内存效率
增长因子越大(如 2×
) :扩容次数少,但可能浪费更多内存(如容量 100 时实际只需 101,但会扩到 200)。
增长因子较小(如 1.5×
) :内存利用率更高,但扩容更频繁。
优化建议
预分配空间 :若已知元素数量,优先使用 reserve()
避免多次扩容。
cpp
vector<int> v;
v.reserve(1000); // 一次性分配足够空间
移动语义 :对非平凡类型(如 std::string
),C++11
后的移动构造减少拷贝开销。
4.3 连续内存的优势与劣势
优势
-
高效访问 :支持随机访问(
O(1)
时间复杂度) -
缓存友好 :内存连续更容易被
CPU
缓存命中,加快处理速度 -
与
C
风格数组兼容 :可使用&v[0]
转换为原生指针
cpp
vector<int> v = { 1,2,3 };
int* p = &v[0];// 可以像数组一样访问
劣势
-
插入/删除成本高(特别是头部或中间)→
O(n)
-
容量增长需整体迁移 → 代价高
-
在多线程环境下共享不安全(需要加锁)
常见操作的时间复杂度
操作 | 时间复杂度 | 说明 |
---|---|---|
push_back()(均摊) | O(1) | 平均时间很快,但扩容时为 O(n) |
pop_back() | O(1) | 删除尾部元素 |
insert()/erase() | O(n) | 从中间或头部插入/删除会移动大量元素 |
随机访问([], at()) | O(1) | 与数组完全一致 |
resize() | O(n) | 如需添加元素,则每个元素都要构造或拷贝 |
5. 算法库协作(STL
算法)
STL
(Standard Template Library)提供了丰富的泛型算法,可以与 std::vector
无缝协作,极大地简化了常见的数据操作(如排序、查找、遍历、转换等)。本章将介绍如何高效使用这些算法,并结合 std::vector
进行示例演示。
5.1 排序(std::sort
+ lambda
)
std::sort
是 STL
中最常用的排序算法,支持自定义排序规则(如 Lambda
表达式)。
基本用法
cpp
#include<iostream>
#include<vector>
#include<algorithm>
vector<int> v = { 5,2,9,1,5,6 };
//默认升序排序
sort(v.begin(), v.end());
//输出 1 2 3 4 5 6 9
for (int num : v) {
cout << num << " ";
}
输出内容:

自定义排序(Lambda
表达式)
cpp
vector<int> v = { 5,2,9,1,5,6 };
//降序排序
sort(v.begin(), v.end(), [](int a, int b) {
return a > b;
});
输出内容:

cpp
vector<string> words = { "apple", "banana", "cherry", "date" };
// 按字符串长度排序
sort(words.begin(), words.end(), [](const string& a, const string& b) {
return a.size() < b.size();
});
for (string s : words) {
cout << s << " ";
}
输出内容:

性能分析
时间复杂度 :O(NlogN)
(基于快速排序或内省排序)。
适用场景 :适用于随机访问容器(如 vector
、array
),不适用于 list
(应使用 list::sort
)。
5.2 查找(std::find
, count
, any_of
等)
STL
提供了多种查找算法,适用于不同需求。
std::find
(查找元素)
cpp
vector<int> v = { 1,2,3,4,5 };
vector<int>::iterator it = find(v.begin(), v.end(), 3);
if (it != v.end()) {
cout << "Found:" << *it << endl; // 输出:Found: 3
}else {
std::cout << "Not found" << std::endl;
}
输出内容:

std::count
(统计出现次数)
cpp
vector<int> v = { 1,2,2,3,4,2,5 };
int cnt = count(v.begin(), v.end(), 2);
cout << "Count of 2:" << cnt << endl;// 输出:Count of 2: 3
输出内容:

std::any_of
(是否存在满足条件的元素)
cpp
vector<int> v = { 1, 3, 5, 7, 9 };
bool has_even = any_of(v.begin(), v.end(), [](int x) {
return x % 2 == 0;
});
cout << "Has even number? " << (has_even ? "Yes" : "No") << endl; // 输出:No
输出内容:

性能分析
算法 | 时间复杂度 | 适用场景 |
---|---|---|
std::find | O(N) | 线性查找,适用于无序数据 |
std::count | O(N) | 统计元素出现次数 |
std::any_of | O(N) | 检查是否存在满足条件的元素 |
5.3 遍历与转换(for_each
, transform
)
std::for_each
(遍历并处理元素)
cpp
vector<int> v = { 1, 2, 3, 4, 5 };
// 打印每个元素
for_each(v.begin(), v.end(), [](int x) {
cout << x << " ";
});// 输出:1 2 3 4 5
输出内容:

std::transform
(转换元素)
cpp
vector<int> v = { 1, 2, 3, 4, 5 };
vector<int> squared(v.size());// 必须预先分配空间
// 计算平方并存储到新容器
transform(v.begin(), v.end(), squared.begin(), [](int x) {
return x * x;
});
输出内容:

std::copy_if
(条件拷贝)
cpp
vector<int> v = { 1, 2, 3, 4, 5 };
vector<int> evens;
//只拷贝偶数
copy_if(v.begin(), v.end(), back_inserter(evens), [](int x) {
return x % 2 == 0;
});
for (int num : evens) {
std::cout << num << " ";
}
输出内容:

性能分析
算法 | 时间复杂度 | 适用场景 |
---|---|---|
std::for_each | O(N) | 替代传统 for 循环,更简洁 |
std::transform | O(N) | 数据转换(如映射、计算) |
std::copy_if | O(N) | 条件筛选数据 |
5.4 综合案例
场景:统计并处理学生成绩
cpp
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
using namespace std;
struct Student{
string name;
int score;
};
int main() {
vector<Student> students = {
{"Alice", 85},
{"Bob", 72},
{"Charlie", 90},
{"David", 65}
};
// 按成绩降序排序
sort(students.begin(), students.end(), [](const Student& a, const Student& b) {
return a.score > b.score;
});
// 查找是否有不及格的学生
bool has_failed = any_of(students.begin(), students.end(), [](const Student& s) {
return s.score < 60;
});
// 提取所有及格学生的名字
vector<string> passed_names;
transform(students.begin(), students.end(), back_inserter(passed_names),
[](const Student& s) {if(s.score>59)return s.name;});
// 输出结果
cout << "Ranking:" << endl;
for (const auto& s : students) {
cout << s.name << ": " << s.score << endl;
}
cout << "Has failed students? " << (has_failed ? "Yes" : "No") <<endl;
cout << "Passed students: ";
for (const auto& name : passed_names) {
std::cout << name << " ";
}
}
输出内容:

6.使用vector
的注意事项
std::vector
是 C++
中最常用的动态数组,但在实际使用中,如果不注意一些关键细节,可能会导致性能问题、迭代器失效甚至未定义行为。
6.1 容量变化对迭代器的影响
问题描述
vector
在扩容(如 push_back
、emplace_back
)或缩容(如 shrink_to_fit
)时,所有迭代器、指针和引用都会失效,因为内存可能被重新分配。
cpp
vector<int> v = { 1,2,3 };
vector<int>::iterator it = v.begin(); //获取迭代器
v.push_back(4); //导致扩容,it失效
cout << *it << endl; //迭代器失效,引发错误
错误显示:

解决方案
使用 reserve
避免不必要的扩容
通过调用 reserve
可以提前申请空间,减少多次扩容,避免迭代器失效。
cpp
vector<int> v ;
v.reserve(100);// 提前预留100个元素的空间
6.2 插入/删除操作的性能
插入和删除操作的性能影响
vector
在头部插入或删除元素时,必须移动所有元素,因此这类操作的时间复杂度为 O(n)
,而尾部插入(push_back
)或删除(pop_back
)通常为 O(1)
(除非触发扩容)。
示例:头部插入的性能
cpp
vector<int> vec = { 1, 2, 3, 4 };
vec.insert(vec.begin(), 0); // 需要移动所有元素,时间复杂度 O(n)
for (int v : vec) {
std::cout << v << " ";
}
优化建议
批量插入 :使用 insert
的区间版本(减少多次移动)。
cpp
vector<int> v = { 1, 2, 3, 4 };
vector<int> src = { 5, 6, 7 };
v.insert(v.end(), src.begin(), src.end()); // 一次插入多个元素
避免频繁头部删除 :如果需要频繁在头部操作,考虑 std::deque
。
6.3 对象拷贝问题(深浅拷贝)
问题描述
vector
存储对象时,元素的插入、删除或扩容可能引发拷贝或移动操作。如果对象管理资源(如动态内存、文件句柄),需正确处理拷贝语义。
示例:浅拷贝陷阱
cpp
class BadString {
public:
char* data; // 动态分配的内存
BadString(const char* str) {
data = new char[strlen(str) + 1];
strcpy(data, str);
}
~BadString() { delete[] data; }
// 缺少拷贝构造函数和赋值运算符!
};
int main() {
vector<BadString> vec;
vec.push_back(BadString("hello")); // 浅拷贝,析构时 double-free!编译错误
}
解决方案
实现深拷贝:自定义拷贝构造函数和赋值运算符。
cpp
class GoodString {
public:
char* data;
GoodString(const char* str) { /* 同前 */ }
~GoodString() { delete[] data; }
// 深拷贝
GoodString(const GoodString& other) {
data = new char[strlen(other.data) + 1];
strcpy(data, other.data);
}
GoodString& operator=(const GoodString& other) {
if (this != &other) {
delete[] data;
data = new char[strlen(other.data) + 1];
strcpy(data, other.data);
}
return *this;
}
};
使用移动语义 (C++11+
):减少拷贝开销。
cpp
class GoodString {
public:
char* data;
// 移动构造函数
GoodString(GoodString&& other) noexcept : data(other.data) {
other.data = nullptr;
}
// 移动赋值运算符
GoodString& operator=(GoodString&& other) noexcept {
if (this != &other) {
delete[] data;
data = other.data;
other.data = nullptr;
}
return *this;
}
};
最佳实践
优先存储智能指针 :如 std::vector<std::unique_ptr<T>>
,避免手动管理资源。
使用 emplace_back
:直接构造对象,避免临时对象拷贝。
cpp
vector<GoodString> vec;
vec.emplace_back("hello"); // 直接在 vector 中构造
6.4 多线程环境下的使用问题
std::vector
不是线程安全容器,如果在多线程环境下同时读写,会导致数据竞争(Data Race)、迭代器失效或未定义行为。
常见问题场景
线程 A 写入(如 push_back
) ,线程 B 读取 → 数据竞争。
线程 A 和线程 B 同时写入 → 可能导致内存损坏或程序崩溃。
扩容时迭代器失效 → 其他线程持有的迭代器/指针/引用可能失效。
错误示例
cpp
vector<int> vec;
void write_data() {
for (int i = 0; i < 1000; ++i) {
vec.push_back(i); // 多线程竞争写入
}
}
void read_data() {
for (int num : vec) { // 多线程竞争读取
cout << num << " ";
}
}
int main() {
thread t1(write_data);
thread t2(read_data); // 未定义行为!
t1.join();
t2.join();
return 0;
}
解决方案:
使用互斥锁(std::mutex
)
cpp
vector<int> vec;
mutex mtx; // 互斥锁
void safe_write_data() {
for (int i = 0; i < 1000; ++i) {
lock_guard<mutex> lock(mtx); // 加锁
vec.push_back(i);
}
}
void safe_read_data() {
lock_guard<mutex> lock(mtx); // 加锁
for (int num : vec) {
cout << num << " ";
}
}
int main() {
thread t1(safe_write_data);
thread t2(safe_read_data); // 安全!
t1.join();
t2.join();
return 0;
}
优点 :简单直接,适用于低并发场景。
缺点:锁粒度大时可能降低性能。
使用读写锁(std::shared_mutex
,C++17
)
cpp
vector<int> vec;
shared_mutex rw_mtx; // 读写锁
void safe_write_data() {
for (int i = 0; i < 1000; ++i) {
unique_lock<shared_mutex> lock(rw_mtx); // 写锁(独占)
vec.push_back(i);
}
}
void safe_read_data() {
shared_lock<shared_mutex> lock(rw_mtx); // 读锁(共享)
for (int num : vec) {
cout << num << " ";
}
}
int main() {
thread t1(safe_write_data);
thread t2(safe_read_data); // 安全!
t1.join();
t2.join();
return 0;
}
优点 :允许多个线程同时读,提高并发性能。
缺点 :C++17
引入,旧编译器可能不支持。
避免共享数据(线程局部存储)
如果数据不需要共享,可以使用 thread_local
或每个线程独立的 vector
:
thread_local std::vector<int> local_vec; // 每个线程独立副本
使用无锁数据结构(如 tbb::concurrent_vector
)
Intel TBB
(Threading Building Blocks)提供线程安全的容器:
cpp
#include <tbb/concurrent_vector.h>
tbb::concurrent_vector<int> concurrent_vec; // 无锁实现
void safe_push() {
for (int i = 0; i < 1000; ++i) {
concurrent_vec.push_back(i); // 线程安全
}
}
优点 :高性能,无需手动加锁。
缺点:需引入第三方库。
6.5 其他注意事项
(1)reserve()
与 resize()
的区别
reserve(n)
:仅预分配内存,不改变 size()
。
resize(n)
:调整 size()
,可能构造或销毁对象。
(2)erase-remove
惯用法
删除满足条件的元素时,优先使用 erase-remove
组合,避免低效的循环删除。
cpp
vector<int> v = { 1, 2, 3, 4, 5 };
v.erase(remove_if(v.begin(), v.end(), [](int x) {
return x % 2 == 0; // 删除偶数
}), v.end());
(3)避免 std::vector<bool>
std::vector<bool>
是特化版本,存储为位压缩,但其"引用"行为怪异。如需位操作,可用 std::bitset
或 std::vector<char>
。
7. 实际应用场景
std::vector
在实际项目中应用广泛,不仅因为它的灵活性和高性能,还因为其良好的 STL
协作能力。
场景 1:游戏开发中的对象管理
在游戏中,需要动态地创建和销毁大量对象,如敌人、子弹、特效等。vector
提供了:
高效的随机访问(例如根据 ID
查找对象)
内存连续,适合批量更新渲染或物理逻辑处理
容量可动态扩展,适应场景变化
cpp
struct GameObject {
int id;
float x, y;
bool isActive;
};
// ID 生成器(静态计数器或随机数)
int generateId() {
// 方案1:静态计数器(适合单线程)
static int counter = 0;
return ++counter;
}
std::vector<GameObject> gameObjects;
// 添加新敌人
void spawnEnemy(float x, float y) {
gameObjects.push_back({generateId(), x, y, true});
}
// 移除失效对象(如被击中的敌人)
void removeInactiveObjects() {
gameObjects.erase(
remove_if(
gameObjects.begin(),
gameObjects.end(),
[](const GameObject& obj) { return !obj.isActive; }
),
gameObjects.end()
);
}
// 随机访问(如碰撞检测)
bool checkCollision(int objId) {
auto it = find_if(
gameObjects.begin(),
gameObjects.end(),
[objId](const GameObject& obj) { return obj.id == objId; }
);
return it != gameObjects.end();
}
场景 2:数据分析中的临时存储
从 CSV
文件读取数据到内存,进行统计计算(如平均值、最大值)。
cpp
vector<double> loadCSV(const string& filename) {
ifstream file(filename);
vector<double> data;
double value;
while (file >> value) {
data.push_back(value);
file.ignore(1, ','); // 跳过逗号
}
return data;
}
void analyzeData(const vector<double>& data) {
double sum = accumulate(data.begin(), data.end(), 0.0);
double avg = sum / data.size();
double max = *max_element(data.begin(), data.end());
cout << "Sum: " << sum << "\n"
<< "Avg: " << avg << "\n"
<< "Max: " << max << endl;
}
int main() {
auto data = loadCSV("data.csv");
analyzeData(data);
return 0;
}
优势:
动态增长:自动适应数据量,无需预设大小。
STL 算法支持:直接使用 std::accumulate、std::max_element 等。
RAII 管理内存:无需手动释放,避免泄漏。
场景 3:替代原生数组
相比于C
风格数组,vector
提供了:
自动管理内存,避免泄漏或越界
提供丰富的成员函数(size()
, at()
, push_back()
等)
与 STL
算法库天然配合(std::sort
, std::find
, std::accumulate
等)
cpp
// C 风格数组
int arr[100];
arr[0] = 42;
// vector 替代
vector<int> arr_vec(100);
arr_vec[0] = 42;
8.总结
vector
的核心优势
-
动态性:支持动态扩容,使用方便灵活
-
高性能:内存连续、支持随机访问,算法兼容性好
-
易用性 :提供丰富的成员函数,语法直观友好,和
C++
算法库天然协作
vector
适用场景
-
元素数量不固定,需要动态增删时
-
频繁随机访问元素的场景(如索引访问、排序)
-
需要与
STL
算法协作 (如sort
、find
、transform
)进行高效数据处理 -
临时或中等规模数据存储需求,如文本处理、游戏状态维护、后台数据缓存等