1. 引言
什么是向量(Vector)?
向量(Vector)是 C++ 标准模板库(STL)中的一种序列容器,能够动态地管理可变大小的数组。与传统的固定大小的数组不同,向量可以根据需要随时调整其大小,提供更高的灵活性和便利性。
向量与数组的比较
特性 | 数组(Array) | 向量(Vector) |
---|---|---|
大小 | 固定大小(编译时或运行时) | 动态可变大小 |
内存管理 | 手动管理(需要预留足够空间) | 自动管理(自动扩展或收缩) |
支持的操作 | 限制较多 | 丰富的成员函数和操作 |
安全性 | 较低(易发生缓冲区溢出) | 较高(通过成员函数进行边界检查) |
与 STL 算法的兼容性 | 低 | 高 |
2. std::vector
基础
2.1 包含头文件
使用 std::vector
需要包含 <vector>
头文件:
1 |
2.2 定义与初始化
定义一个整数向量:
1 | std::vector<int> numbers; |
定义一个字符串向量:
1 |
|
初始化向量:
默认初始化:
1
std::vector<int> vec1; // 空向量
指定大小和默认值:
1
std::vector<int> vec2(5, 10); // 5个元素,值均为10
使用初始化列表:
1
std::vector<int> vec3 = {1, 2, 3, 4, 5};
拷贝构造:
1
std::vector<int> vec4(vec3); // 复制vec3
移动构造:
1
std::vector<int> vec5(std::move(vec4)); // 移动vec4到vec5
示例代码:
1 |
|
输出:
1 | vec2: 10 10 10 10 10 |
2.3 向量的大小与容量
- **
size()
**:返回向量中元素的数量。 - **
capacity()
**:返回向量目前为止分配的存储容量。 - **
empty()
**:检查向量是否为空。
示例代码:
1 |
|
输出示例:
1 | Size: 3 |
注意: capacity()
并不一定精确匹配 size()
,它表示在需要重新分配内存之前,向量可以容纳的元素数量。
3. 向量的基本操作
3.1 添加与删除元素
- **
push_back()
**:在向量末尾添加一个元素。 - **
pop_back()
**:移除向量末尾的元素。 - **
insert()
**:在指定位置插入元素。 - **
erase()
**:移除指定位置的元素或范围内的元素。 - **
clear()
**:移除所有元素。
示例代码:
1 |
|
输出:
1 | After push_back: 10 20 30 |
3.2 访问元素
- **
operator[]
**:通过索引访问元素。 - **
at()
**:通过索引访问元素,带边界检查。 - **
front()
**:访问第一个元素。 - **
back()
**:访问最后一个元素。
示例代码:
1 |
|
输出:
1 | First fruit: Apple |
3.3 遍历向量
- 使用范围
for
循环 - 使用传统
for
循环 - 使用迭代器
示例代码:
1 |
|
输出:
1 | Using range-based for loop: 1 2 3 4 5 |
3.4 修改元素
- 通过索引或迭代器修改
- 使用
assign()
重新赋值 - 替换整个向量内容
示例代码:
1 |
|
输出:
1 | Modified vector: 10 25 35 40 55 |
4. 向量的高级用法
4.1 嵌套向量(二维向量)
向量可以包含其他向量,形成多维数组结构。
示例代码:二维向量
1 |
|
输出:
1 | Matrix: |
4.2 向量与其他数据结构结合
向量可以与结构体、类等其他数据结构结合使用,增强数据组织能力。
示例代码:向量与结构体结合
1 |
|
输出:
1 | ID: 1001, Name: Alice, Grade: 89.5 |
4.3 使用迭代器操作向量
迭代器是一种指针类型,用于遍历和操作容器中的元素。
示例代码:使用迭代器
1 |
|
输出:
1 | After modifying: 15 25 35 45 55 |
5. 常用算法与向量
5.1 排序
可以使用 <algorithm>
头文件中的 sort()
函数对向量进行排序。
示例代码:对整数向量排序
1 |
|
输出:
1 | Before sorting: 50 20 40 10 30 |
自定义排序规则:降序
1 |
|
输出:
1 | After sorting in descending order: 50 40 30 20 10 |
5.2 反转
使用 reverse()
函数可以反转向量中的元素顺序。
示例代码:
1 |
|
输出:
1 | Before reversing: A B C D E |
5.3 查找
使用 find()
函数可以在向量中查找特定元素。
示例代码:
1 |
|
输出:
1 | Cherry found at position 2 |
6. 向量的性能与优化
6.1 内存管理
向量会动态地管理内存,自动调整其容量以适应新增或删除的元素。频繁的内存分配可能会影响性能。
6.2 预留空间
使用 reserve()
可以提前为向量分配足够的内存,减少内存重新分配的次数,提高性能。
示例代码:
1 |
|
输出示例:
1 | Capacity after reserve(1000): 1000 |
6.3 收缩容量
使用 shrink_to_fit()
可以请求收缩向量的容量以匹配其大小,释放多余的内存。
示例代码:
1 |
|
输出示例:
1 | Capacity before adding: 1000 |
7. 示例项目
示例项目1:学生信息管理系统
需求分析:
创建一个程序,管理学生的信息,包括添加、删除、显示和查找学生。每个学生包含ID、姓名和成绩。
代码实现:
1 |
|
运行示例:
1 | === Student Management System === |
代码解析:
- 结构体定义: 定义了一个
Student
结构体,包含id
、name
和grade
。 - 功能函数:
addStudent
:添加新学生。deleteStudent
:根据 ID 删除学生。displayStudents
:显示所有学生的信息。findStudent
:根据 ID 查找并显示学生信息。
- 主函数: 提供一个菜单驱动的用户界面,允许用户选择不同的操作。
示例项目2:动态库存管理系统
需求分析:
创建一个程序,管理库存中的商品信息,包括添加、删除、更新和显示商品。每个商品包含商品ID、名称和数量。
代码实现:
1 |
|
运行示例:
1 | === Inventory Management System === |
代码解析:
- 结构体定义: 定义了一个
Product
结构体,包含id
、name
和quantity
。 - 功能函数:
addProduct
:添加新商品。deleteProduct
:根据 ID 删除商品。updateProductQuantity
:根据 ID 更新商品数量。displayProducts
:显示所有商品的信息。
- 主函数: 提供一个菜单驱动的用户界面,允许用户选择不同的操作。