当前位置: 首页 > news >正文

C++ vector 完全指南:从入门到精通

vector 是 C++ 中最强大且最常用的容器之一,本文将带你全面掌握 vector 的使用技巧!

一、什么是 vector?

std::vector 是 C++ 标准模板库(STL)中的动态数组容器,它能够自动管理内存,在运行时根据需要动态调整大小。相比于传统数组,vector 提供了更强大的功能和更便捷的操作方式。

vector 的核心优势

  • 动态扩容:自动处理内存分配和释放

  • 随机访问:支持 O(1) 复杂度的元素访问

  • 丰富接口:提供多种操作方法

  • 类型安全:模板化的容器保证类型安全

  • 内存连续:元素在内存中连续存储

二、创建和初始化 vector

1. 基本声明方式

#include <vector>
using namespace std;// 创建空vector
vector<int> nums;// 创建指定大小的vector(默认初始化为0)
vector<double> prices(5); // 5个0.0// 创建指定大小并初始化的vector
vector<string> names(3, "Unknown"); // 3个"Unknown"

2. 初始化列表(C++11起)

// 列表初始化
vector<int> primes = {2, 3, 5, 7, 11};// 从数组初始化int arr[ ] = {1, 2, 3, 4, 5};vector<int> vec(arr, arr + sizeof(arr)/sizeof(arr[0]));// 复制另一个vector
vector<int> copyVec = primes;

三、vector 的基本操作

1. 添加元素

vector<int> v;// 尾部添加元素
v.push_back(10); // v: [10]
v.push_back(20); // v: [10, 20]
v.push_back(30); // v: [10, 20, 30]// 高效构造并添加(C++11)
v.emplace_back(40); // v: [10, 20, 30, 40]// 在指定位置插入
v.insert(v.begin() + 1, 15); // v: [10, 15, 20, 30, 40]

2. 访问元素

// 使用下标访问(不检查边界)
cout << v[0]; // 10// 使用at()访问(边界检查)
cout << v.at(1); // 15// 访问首尾元素
cout << v.front(); // 10
cout << v.back();  // 40// 遍历vector(C++11范围for循环)
for (int num : v) {cout << num << " ";
}
// 输出: 10 15 20 30 40

3. 删除元素

// 删除尾部元素
v.pop_back(); // v: [10, 15, 20, 30]// 删除指定位置元素
v.erase(v.begin() + 1); // v: [10, 20, 30]// 删除指定范围的元素
v.erase(v.begin(), v.begin() + 2); // v: [30]// 清空vectorv.clear(); // v: [ ]

4. 大小与容量管理

vector<int> vec = {1, 2, 3};cout << "元素数量: " << vec.size();      // 3
cout << "最大容量: " << vec.capacity();  // 可能大于3// 调整大小(多出部分默认初始化为0)
vec.resize(5); // vec: [1, 2, 3, 0, 0]// 预留空间(避免多次重分配)
vec.reserve(100); // 容量至少为100// 检查是否为空
if (vec.empty()) {cout << "vector为空!";
}

四、vector 内存管理机制

1. 动态扩容原理

vector 在内存中连续存储元素,当添加元素超过当前容量时:

  1. 分配新的更大的内存块(通常是当前大小的1.5-2倍)

  2. 将原有元素复制/移动到新内存

  3. 释放原有内存

  4. 添加新元素

vector<int> v;
cout << "初始容量: " << v.capacity() << endl; // 0for (int i = 0; i < 10; i++) {v.push_back(i);cout << "大小: " << v.size() << " 容量: " << v.capacity() << endl;
}

典型输出:

大小:1 容量:1
大小:2 容量:2
大小:3 容量:4
大小:4 容量:4
大小:5 容量:8
大小:6 容量:8
大小:7 容量:8
大小:8 容量:8
大小:9 容量:16
大小:10 容量:16

2. 优化技巧:reserve()

// 低效方式(可能多次重分配)
vector<int> inefficient;
for (int i = 0; i < 1000; i++) {inefficient.push_back(i);
}// 高效方式(一次性预留空间)
vector<int> efficient;
efficient.reserve(1000); // 避免多次重分配
for (int i = 0; i < 1000; i++) {efficient.push_back(i);
}

五、迭代器使用

vector<int> nums = {10, 20, 30, 40, 50};// 1. 常规迭代器
cout << "正向遍历: ";
for (auto it = nums.begin(); it != nums.end(); ++it) {cout << *it << " ";
}// 2. 反向迭代器
cout << "\n反向遍历: ";
for (auto rit = nums.rbegin(); rit != nums.rend(); ++rit) {cout << *rit << " ";
}// 3. 常量迭代器(防止修改)
for (auto cit = nums.cbegin(); cit != nums.cend(); ++cit) {// *cit = 100; // 错误!不能修改cout << *cit << " ";
}

六、vector 高级技巧

1. 二维 vector(矩阵)

// 创建3x4矩阵(初始化为0)
vector<vector<int>> matrix(3, vector<int>(4, 0));// 访问元素
matrix[1][2] = 5; // 第2行第3列// 遍历二维vector
for (const auto& row : matrix) {for (int num : row) {cout << num << " ";}cout << endl;
}

2. 使用 swap 释放内存

vector<int> bigVec(1000000); // 占用大量内存// 传统clear()不会释放内存
bigVec.clear(); 
cout << "容量: " << bigVec.capacity(); // 仍然很大// 使用swap技巧释放内存
vector<int>().swap(bigVec);
cout << "容量: " << bigVec.capacity(); // 0

3. 元素排序和搜索

vector<int> numbers = {5, 3, 8, 1, 4};// 排序
sort(numbers.begin(), numbers.end()); // [1, 3, 4, 5, 8]// 二分查找(要求已排序)
if (binary_search(numbers.begin(), numbers.end(), 5)) {cout << "5存在于vector中";
}// 查找元素位置
auto it = find(numbers.begin(), numbers.end(), 4);
if (it != numbers.end()) {cout << "找到4,位置: " << distance(numbers.begin(), it);
}

七、vector 使用注意事项

迭代器失效问题

  • 添加元素可能导致所有迭代器失效

  • 删除元素会使被删除元素之后的迭代器失效

避免在循环中插入/删除

// 危险!循环中删除可能导致迭代器失效
for (auto it = vec.begin(); it != vec.end(); ) {if (*it % 2 == 0) {it = vec.erase(it); // 正确方式} else {++it;}
}

对象 vs 指针

  • 存储对象:适用于小型对象

  • 存储指针:适用于大型对象或多态

性能考虑

操作

时间复杂度

随机访问

O(1)

尾部插入/删除

O(1)

头部插入/删除

O(n)

中间插入/删除

O(n)

八、完整示例程序

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;int main() {// 创建并初始化vectorvector<int> scores = {85, 92, 78, 90, 88};// 添加元素scores.push_back(95);scores.insert(scores.begin(), 80);// 删除元素scores.pop_back();scores.erase(scores.begin() + 2);// 遍历vectorcout << "当前成绩: ";for (int score : scores) {cout << score << " ";}cout << endl;// 排序sort(scores.begin(), scores.end());// 查找auto it = find(scores.begin(), scores.end(), 90);if (it != scores.end()) {cout << "找到90分,位置: " << distance(scores.begin(), it) << endl;}// 容量管理cout << "元素数量: " << scores.size() << endl;scores.reserve(20);cout << "当前容量: " << scores.capacity() << endl;return 0;
}

总结

vector 是 C++ 中最常用且功能强大的容器之一,其核心优势在于:

  • 动态内存管理,简化开发

  • 连续存储提供高效的随机访问

  • 丰富的成员函数满足各种需求

  • 与算法库完美配合

掌握 vector 的使用是成为高效 C++ 开发者的关键一步。通过合理使用 reserve() 优化性能,注意迭代器失效问题,并善用 STL 算法,你可以在项目中充分发挥 vector 的强大功能!

http://www.lqws.cn/news/557173.html

相关文章:

  • 源码运行效果图(六)
  • 【HarmonyOS Next之旅】DevEco Studio使用指南(三十八) -> 构建HAR
  • 基于springboot的海产品交易系统
  • 【数据标注师】3D标注
  • JWT认证性能优化实战指南
  • 《从 0 到 1 掌握正则表达式:解析串口数据的万能钥匙》
  • springboot+Vue逍遥大药房管理系统
  • 创建套接字时和填充地址时指定类型的异同
  • C++泛型编程2 - 类模板
  • 【数论】P11169 「CMOI R1」Bismuth / Linear Sieve|普及+
  • 嵌入式硬件与应用篇---寄存器GPIO控制
  • 进阶向:Flask框架详解,从零开始理解Web开发利器
  • Odoo邮箱别名使用指南:从配置到业务流程自动化
  • C# 委托(为委托添加方法和从委托移除方法)
  • docker部署后端服务的脚本
  • Golang JSON 标准库用法详解
  • Foundry测试实战:解锁区块链测试新姿势
  • Java 大视界 -- Java 大数据机器学习模型在金融市场高频交易策略优化与风险控制中的应用(327)
  • 单调栈一文深度解析
  • NLP——文本预处理(下)
  • 翻译服务器
  • Redis高级数据结构深度解析:BitMap、布隆过滤器、HyperLogLog与Geo应用实践
  • 趣味数据结构之——数组
  • Java 使用 Easy Excel 进行 Excel 数据导入导出
  • 一分钟了解思路链提示词(Chain-of-thought Prompting)
  • uni-app manifest.json 配置:定制化应用的各项功能和行为
  • 基于Pandas和FineBI的昆明职位数据分析与可视化实现(二)- 职位数据清洗与预处理
  • 《自动控制原理 》- 第 1 章 自动控制的基本原理与方式
  • Linux基本指令篇 —— more指令
  • PostgreSQL 中,若需显示 不在 `IN` 子句列表中的数据