Vector
1. Vector 基础概念
1.1 内存结构
std::vector
是 C++ 标准模板库(STL)中的一个动态数组容器,其内存结构由三部分组成:
- 动态数组指针
data
:指向实际存储元素的连续内存区域,这是std::vector
的核心,使得其能够通过下标快速访问元素。 - 当前元素数量
size
:记录当前存储在std::vector
中的元素个数,反映了std::vector
中实际使用的内存大小。 - 预分配内存容量
capacity
:表示std::vector
已经分配的内存大小,通常大于或等于size
。当向std::vector
中添加元素时,如果size
超过了capacity
,std::vector
会自动扩容,重新分配更大的内存空间,并将原有元素复制到新内存中,这一过程会带来额外的性能开销。
这种内存结构使得 std::vector
兼具动态数组的灵活性和静态数组的高效性,能够根据需要自动调整大小,同时保证了对元素的快速随机访问。
1.2 初始化方法
std::vector
提供了多种初始化方法,以满足不同的使用场景:
-
默认初始化:创建一个空的
std::vector
,不包含任何元素,size
和capacity
均为 0。std::vector<int> v1;
-
指定大小初始化:创建一个包含指定数量元素的
std::vector
,所有元素均初始化为默认值(对于基本数据类型为 0,对于自定义类型则调用默认构造函数)。std::vector<int> v2(5); // 创建一个包含 5 个 0 的 vector
-
指定大小和初始值初始化:创建一个包含指定数量元素的
std::vector
,并将所有元素初始化为指定的值。std::vector<int> v3(3, 100); // 创建一个包含 3 个 100 的 vector
-
列表初始化(C++11 及以上版本支持):使用花括号
{}
将一组元素初始化到std::vector
中,这种方式直观且方便。std::vector<int> v4 = { 1, 2, 3}; // 使用列表初始化
-
拷贝初始化:通过已有的
std::vector
创建一个新的std::vector
,新std::vector
中的元素是原std::vector
中元素的副本。std::vector<int> v5(v4); // 拷贝初始化
这些初始化方法为用户提供了灵活的选择,能够根据具体需求快速创建并初始化 std::vector
,从而提高编程效率。# 2. 元素访问与遍历
2.1 访问方式对比
std::vector
提供了多种访问元素的方式,每种方式都有其特点和适用场景。以下是几种常见的访问方式对比:
访问方式 | 代码示例 | 越界检查 | 性能 | 适用场景 |
---|---|---|---|---|
下标操作符 [] |
v[0] |
无 | 快速访问 | 已知索引且确保安全时 |
at() 方法 |
v.at(0) |
有 | 较慢 | 需要安全访问时 |
迭代器 | *it |
无 | 快速访问 | 遍历或算法操作 |
-
下标操作符
[]
:通过索引直接访问元素,性能高,但不进行越界检查。如果索引超出范围,程序可能会崩溃或出现未定义行为。std::vector<int> v = { 1, 2, 3}; int first = v[0]; // 访问第一个元素
-
at()
方法:提供范围检查,如果索引超出范围,会抛出std::out_of_range
异常。虽然安全性更高,但性能略低于下标操作符。std::vector<int> v = { 1, 2, 3}; int first = v.at(0); // 安全访问第一个元素
-
迭代器:通过迭代器访问元素,适用于遍历整个容器或在算法中使用。迭代器提供了指针类似的语法,但不进行越界检查。
std::vector<int> v = { 1, 2, 3}; for (auto it = v.begin(); it != v.end(); ++it) { std::cout << *it << " "; }
2.2 遍历流程
遍历 std::vector
的过程可以通过迭代器或范围 for
循环实现。以下是遍历的流程图和代码实现: