C++ STL Vector 入门与实战全攻略

在C++编程学习路上,数组是我们最早接触的线性容器,但原生数组有着致命短板:固定长度、无法动态扩容、容易越界、内存管理繁琐。

而 STL 中的 vector 完美解决了这些痛点,它是动态可变长数组,也是 C++ STL 最常用、最重要的容器之一。不管是算法刷题、项目开发、数据存储, vector 都是刚需工具。

本文从零带你系统吃透 vector :底层原理、构造初始化、常用接口、遍历方式、扩容机制、避坑要点、实战场景,一篇搞定入门到实战。

一、Vector 是什么?

  1. 核心定义

vector 是 C++ STL 提供的序列式容器,底层采用连续线性内存空间实现,本质就是可以自动扩容的动态数组。

  1. Vector 与原生数组区别

特性 原生数组 vector

长度 固定不可变 动态自动扩容缩容

内存 栈/静态内存 堆上动态分配

越界检查 无,崩溃风险高 提供 at() 安全访问

赋值拷贝 不支持直接整体赋值 支持直接拷贝、赋值

接口 无封装接口 丰富增删查改接口

  1. 底层特点
  • 内存连续分布,支持随机访问,下标访问效率极高;

  • 插入删除中间元素效率低,需要挪动数据;

  • 尾部增删效率极高,O(1) 级别;

  • 自动管理内存,无需手动 new/delete 。

二、Vector 头文件与基础语法

使用 vector 必须包含头文件:

cpp

#include <vector>

using namespace std; // 初学可直接使用,项目建议不用

基础定义格式:

cpp

vector<存储类型> 容器名;

示例:

cpp

vector<int> v1; // 存储int

vector<double> v2; // 存储浮点

vector<string> v3; // 存储字符串

vector<vector<int>> v4; // 二维vector,等价二维数组

三、Vector 常见构造与初始化

  1. 空构造

cpp

vector<int> v;

  1. 指定个数初始化

cpp

// 5个元素,初始值都是0

vector<int> v(5);

  1. 指定个数+初始值

cpp

// 5个元素,全部初始化为10

vector<int> v(5, 10);

  1. 拷贝构造

cpp

vector<int> v1 = {1,2,3};

vector<int> v2(v1);

  1. 列表初始化(C++11 推荐)

cpp

vector<int> v = {1, 2, 3, 4, 5};

  1. 迭代器区间构造

cpp

vector<int> v1 = {1,2,3,4};

vector<int> v2(v1.begin(), v1.end());

四、Vector 常用核心接口

  1. 容量与大小相关

cpp

v.size(); // 当前元素个数

v.capacity(); // 容量,已分配内存能存多少

v.empty(); // 判断是否为空

v.resize(n); // 改变有效元素个数

v.reserve(n); // 预留容量,只开空间不初始化元素

重点区分:

  • size() :实际元素数量

  • capacity() :底层内存总容量

  • reserve 只扩容不填值, resize 会改变元素个数并初始化

  1. 增删操作

cpp

v.push_back(x); // 尾部插入元素

v.pop_back(); // 删除尾部元素

v.insert(pos, x); // 指定位置插入

v.erase(pos); // 删除指定位置元素

v.clear(); // 清空所有元素,不释放容量

  1. 元素访问

cpp

vi; // 下标访问,不做越界检查

v.at(i); // 安全访问,越界抛异常

v.front(); // 获取首元素

v.back(); // 获取尾元素

五、Vector 四种遍历方式

  1. 下标遍历(最常用)

cpp

vector<int> v = {1,2,3,4};

for(int i = 0; i < v.size(); i++)

{

cout << vi << " ";

}

  1. 迭代器遍历

cpp

for(vector<int>::iterator it = v.begin(); it != v.end(); ++it)

{

cout << *it << " ";

}

  1. 范围 for 循环(C++11 极简推荐)

cpp

for(auto val : v)

{

cout << val << " ";

}

  1. 反向迭代器遍历

cpp

for(vector<int>::reverse_iterator it = v.rbegin(); it != v.rend(); ++it)

{

cout << *it << " ";

}

六、Vector 扩容机制(核心重点)

  1. 扩容规则

不同编译器略有差异:

  • VS:每次扩容 1.5 倍

  • GCC:每次扩容 2 倍

  1. 扩容过程

  2. 开辟一块更大的新内存空间;

  3. 将旧空间所有元素拷贝到新空间;

  4. 释放旧内存;

  5. 迭代器失效。

  6. 开发建议

如果提前知道大概数据量,先用 reserve() 预留容量,避免多次频繁扩容,提升程序效率。

示例:

cpp

vector<int> v;

v.reserve(1000); // 提前预留1000容量,减少扩容次数

七、二维 Vector 用法(实战高频)

等价于二维数组,常用于矩阵、图邻接表:

cpp

// 3行4列,初始化为0

vector<vector<int>> arr(3, vector<int>(4, 0));

// 遍历二维vector

for(int i = 0; i < arr.size(); i++)

{

for(int j = 0; j < arri.size(); j++)

{

cout << arrij << " ";

}

cout << endl;

}

八、使用 Vector 常见避坑点

  1. 不要越界访问: \[\] 不检查越界,程序直接崩溃,安全场景用 at() ;

  2. 迭代器失效问题:扩容、插入、删除后,原有迭代器会失效,需重新获取;

  3. 区分 resize 和 reserve:需要元素就用 resize,只预分配空间用 reserve;

  4. clear 只清空元素,不释放容量,如需释放可配合 swap 技巧;

  5. 频繁在中间插入删除不要用 vector,改用 list 。

九、实战小案例:用 Vector 实现数据录入与筛选

需求:输入若干整数,筛选出偶数并打印

cpp

#include <iostream>

#include <vector>

using namespace std;

int main()

{

vector<int> v;

int num;

// 录入数据,输入-1结束

while(cin >> num && num != -1)

{

v.push_back(num);

}

// 筛选偶数

cout << "所有偶数:" << endl;

for(auto val : v)

{

if(val % 2 == 0)

{

cout << val << " ";

}

}

return 0;

}

十、总结

  1. vector 是动态数组,替代原生固定数组,开发必备;

  2. 底层连续内存,随机访问快、中间增删慢;

  3. 掌握构造、容量接口、增删、四种遍历是入门核心;

  4. 理解扩容机制、迭代器失效、resize/reserve 区别是进阶关键;

  5. 二维 vector 可轻松替代二维数组,算法和项目都高频使用。

相关推荐
凡人叶枫1 天前
Effective C++ 条款17:以独立语句将 newed 对象置入智能指针
java·linux·开发语言·c++·算法
凡人叶枫1 天前
Effective C++ 条款16:成对使用 new 和 delete 时要采取相同形式
开发语言·c++·effective c++
不吃土豆的马铃薯1 天前
C++ 高性能网络缓冲区 Buffer 源码解析
linux·服务器·开发语言·网络·c++
caimouse1 天前
Reactos 第1章 概述
c语言·开发语言·架构
.千余1 天前
【C++】C++继承入门(下):友元、静态成员与菱形继承的底层逻辑
开发语言·c++·笔记·学习·其他
初中就开始混世的大魔王1 天前
6 Fast DDS-传输层
开发语言·c++·中间件·信息与通信
啊森要自信1 天前
【GUI自动化测试】控件、鼠标键盘操作与多场景自动化
c语言·开发语言·python·adb·ipython
代码中介商1 天前
C++ 智能指针完全指南(三):weak_ptr 与循环引用
开发语言·c++
BestOrNothing_20151 天前
ROS2 C++ 小车控制完整实战(二):自定义 msg 消息发布与订阅保姆级教程
c++·ros2·subscriber·publisher·msg·topic通信·自定义接口
lpl3129055091 天前
skynet 共享数据原理
服务器·c语言·lua