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

v[i]; // 下标访问,不做越界检查

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 << v[i] << " ";

}

  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 < arr[i].size(); j++)

{

cout << arr[i][j] << " ";

}

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 可轻松替代二维数组,算法和项目都高频使用。

相关推荐
qeen872 小时前
【算法笔记】简单贪心
c++·笔记·算法·贪心算法
AI进化营-智能译站2 小时前
ROS2 C++开发系列19-枚举定义机器人状态机|随机数生成仿真测试数据流
java·c++·ai·机器人
迷途之人不知返2 小时前
深入讨论模板
c++
AI进化营-智能译站2 小时前
ROS2 C++开发系列18-STL容器实战:deque缓存激光雷达数据|priority_queue调度任务
开发语言·c++·缓存·ai
hehelm3 小时前
C++11 新特性
c++
我不是懒洋洋3 小时前
【数据结构】排序算法(直接插入排序、希尔排序、选择排序、堆排序、冒泡排序、快速排序、归并排序、计数排序)
c语言·数据结构·c++·经验分享·算法·排序算法
邪修king3 小时前
UE5:C++ 实现 游戏逻辑 ↔ UI 双向联动
c++·游戏·ue5
辛苦才能3 小时前
数据结构--排序--插入排序(C语言,重点排序面试和比赛都会考察)
c语言·数据结构·面试
SuperByteMaster11 小时前
keil 工程 .gitignore配置文件
c语言