### C++ `vector` 使用详解
#### 一、概述
`std::vector` 是 C++ 标准模板库 (STL) 中一个非常重要的容器类,它提供了动态数组的功能,支持随机访问,并且可以根据需要自动扩展内存空间。由于 `vector` 的强大功能以及易于使用的特性,它成为了开发人员在处理数据集合时的首选容器之一。本文将详细介绍 `vector` 在 C++ 中的使用方法及其一些关键特性,包括元素访问方式的选择、调整容器大小的方法等。
#### 二、元素访问方式
##### 1. `[]` 操作符与 `.at()` 方法的区别
在 C++ 中,`std::vector` 提供了两种访问元素的方式:`[]` 操作符和 `.at()` 方法。
- **`[]` 操作符**:该操作符提供了一种快速访问元素的方式,但是它不会检查索引的有效性。如果提供的索引超出了向量的有效范围,则可能导致未定义行为,例如程序崩溃或数据损坏。
- **`.at()` 方法**:与 `[]` 操作符不同,`.at()` 方法会在访问元素之前进行边界检查。如果提供的索引无效,它将抛出一个 `std::out_of_range` 异常。
**示例代码分析**:
```cpp
void f(vector<int>& v) {
v[0]; // A: 使用 [] 操作符访问第一个元素
v.at(0); // B: 使用 .at() 方法访问第一个元素
}
```
- 如果 `v` 非空,则这两行代码的行为相同。
- 如果 `v` 为空,则 `B` 行会抛出 `std::out_of_range` 异常,而 `A` 行的行为未定义,具体取决于编译器和运行环境。
##### 2. 选择合适的访问方式
- 当确定容器不为空且索引有效时,使用 `[]` 操作符可以获得更好的性能。
- 当需要对索引的有效性进行检查时,使用 `.at()` 方法可以避免潜在的运行时错误。
#### 三、调整 `vector` 容器的大小
##### 1. `reserve()` 方法
`reserve()` 方法用于预先分配足够的内存空间,以减少未来的重新分配操作。这有助于提高程序的性能,尤其是在已知容器的大致大小时。
**示例代码分析**:
```cpp
vector<int> v;
v.reserve(2);
assert(v.capacity() >= 2);
```
- **`v.reserve(2);`**:尝试为 `vector` 分配足够的内存空间,使得容量至少为 2。
- **`assert(v.capacity() >= 2);`**:断言检查 `vector` 的容量是否至少为 2。需要注意的是,实际容量可能大于 2,这是因为 `vector` 的扩容策略通常采用指数增长的方式来提高效率。
##### 2. 关于 `reserve()` 的注意事项
- `reserve()` 不改变容器的实际大小,只是预分配足够的内存空间。
- 使用 `reserve()` 时,需要确保指定的大小合理,以避免过度分配内存导致的资源浪费。
- 应当理解 `vector` 的内部扩容机制,通常 `vector` 会按照一定的比例(例如 1.5 倍或 2 倍)增长容量,因此,即使通过 `reserve()` 设置了一个特定的容量值,实际容量也可能会大于该值。
#### 四、结论
`std::vector` 作为 C++ 中最常用的容器之一,提供了灵活而强大的功能。正确理解和使用 `vector` 及其成员函数对于编写高效、可靠的 C++ 程序至关重要。本文重点介绍了 `vector` 的两种主要元素访问方式以及如何合理调整容器的大小。希望这些知识能够帮助开发者更好地利用 `vector`,避免常见的陷阱和错误。