C++笔记 STL——vector

在 C++ 的 STL(标准模板库)中,vector 是最常用、最基础的序列式容器,本质是动态数组。它解决了传统静态数组长度固定、无法灵活扩容的痛点,支持随机访问、尾部高效增删元素,是开发中处理可变长度数组的首选工具。

本文从基础概念、核心操作、常用 API、底层原理、使用场景五个维度,整理 vector 的核心知识点,适合学习和复习使用。

一、vector 基础认知

示例:

表格

方法 作用
size() 获取元素个数
empty() 判断是否为空(空返回 true)
capacity() 获取当前容量
resize(n) 调整元素个数为 n,多删少补 0
reserve(n) 预分配容量,避免频繁扩容
shrink_to_fit() 释放多余容量,capacity=size
  1. 本质 :封装了动态数组的类模板,内存连续存放,支持随机访问(和数组一样通过下标访问元素)。

  2. 特点

    • 内存自动管理,无需手动释放;
    • 支持动态扩容(元素超出容量时自动分配更大内存);
    • 尾部增删元素效率极高,中间 / 头部增删需要移动元素,效率较低;
    • 迭代器支持随机访问。
  3. 头文件 :使用 vector 必须包含头文件

    cpp 复制代码
    #include <vector>
    using namespace std;  // 日常开发常用,简化代码

    二、vector 的定义与初始化

    vector 支持多种初始化方式,覆盖开发中绝大多数场景:

    cpp 复制代码
    #include <iostream>
    #include <vector>
    using namespace std;
    
    int main() {
        // 1. 空容器初始化(最常用)
        vector<int> v1;
    
        // 2. 指定容量,初始值为0(数值类型)
        vector<int> v2(5);  // 5个元素,值都为0
    
        // 3. 指定容量+初始值
        vector<int> v3(5, 10);  // 5个元素,值都为10
    
        // 4. 列表初始化(C++11及以上)
        vector<int> v4 = {1,2,3,4,5};
        vector<int> v5{1,2,3};
    
        // 5. 拷贝初始化
        vector<int> v6(v4);  // 拷贝v4所有元素
    
        // 6. 区间初始化
        vector<int> v7(v4.begin(), v4.begin()+3);  // 拷贝v4前3个元素
    
        return 0;
    }

    三、vector 核心常用 API

    vector 的 API 分为访问元素、增删元素、容量操作、迭代器四大类,是必须掌握的核心。

    1. 元素访问

    表格

    方法 作用 备注
    v[i] 访问第 i 个元素 不检查越界,效率高
    v.at(i) 访问第 i 个元素 检查越界,越界抛异常
    v.front() 获取第一个元素 容器非空时使用
    v.back() 获取最后一个元素 容器非空时使用
    v.data() 获取底层数组首地址 用于兼容 C 语言接口

    示例:

    cpp 复制代码
    vector<int> v = {10,20,30};
    cout << v[1] << endl;      // 20
    cout << v.at(2) << endl;   // 30
    cout << v.front() << endl; // 10
    cout << v.back() << endl;  // 30

    2. 增加元素

    表格

    方法 作用 效率
    push_back(val) 尾部添加元素 极高(O (1))
    emplace_back(val) 尾部原位构造元素 C++11,比 push_back 更高效
    insert(pos, val) 在迭代器 pos 处插入元素 低(O (n),需移动元素)
    insert(pos, n, val) 在 pos 处插入 n 个 val

    示例:

    cpp 复制代码
    vector<int> v;
    v.push_back(1);   // 尾部加1
    v.emplace_back(2); // 尾部加2,推荐使用
    v.insert(v.begin(), 0); // 头部插入0
    v.insert(v.end(), 2, 3); // 尾部插入两个3
    // 最终:0,1,2,3,3

    3. 删除元素

    表格

    方法 作用
    pop_back() 删除最后一个元素
    erase(pos) 删除迭代器 pos 指向的元素
    erase(beg, end) 删除区间 [beg,end) 内的元素
    clear() 清空所有元素(容量不变)

    示例:

    cpp 复制代码
    vector<int> v = {1,2,3,4,5};
    v.pop_back();    // 删除5
    v.erase(v.begin()+1); // 删除2
    v.clear();       // 清空所有元素

    4. 容量与大小操作

    区分两个核心概念

  4. size :当前容器中实际元素的个数

  5. capacity :容器当前能容纳的最大元素个数(已分配的内存)。

表格

方法 作用
size() 获取元素个数
empty() 判断是否为空(空返回 true)
capacity() 获取当前容量
resize(n) 调整元素个数为 n,多删少补 0
reserve(n) 预分配容量,避免频繁扩容
shrink_to_fit() 释放多余容量,capacity=size

示例:

cpp 复制代码
vector<int> v;
v.reserve(10); // 预分配10个元素的容量,提升效率
v.push_back(1);
cout << v.size() << endl;  // 1
cout << v.capacity() << endl; // 10
v.resize(5);  // 元素个数变为5,新增元素默认0

5. 迭代器(遍历专用)

vector 的迭代器是随机访问迭代器 ,支持++、--、+、-操作,和指针用法几乎一致。

常用遍历方式:

cpp 复制代码
vector<int> v = {1,2,3,4};

// 方式1:下标遍历(最简单)
for(int i=0; i<v.size(); i++){
    cout << v[i] << " ";
}

// 方式2:迭代器遍历(通用,所有容器都支持)
for(vector<int>::iterator it = v.begin(); it != v.end(); it++){
    cout << *it << " ";
}

// 方式3:C++11范围for(最简洁)
for(int num : v){
    cout << num << " ";
}

四、vector 底层原理:动态扩容机制

vector 的核心优势是动态扩容 ,但扩容不是按需增加,而是成倍分配内存(不同编译器规则不同):

  • VS 编译器:扩容为原来的 1.5 倍
  • GCC 编译器:扩容为原来的 2 倍

扩容流程:

  1. size == capacity时,再次插入元素会触发扩容;
  2. 申请一块更大的连续内存;
  3. 将旧内存的所有元素拷贝 / 移动到新内存;
  4. 释放旧内存,更新迭代器、指针、引用。

⚠️ 注意 :扩容会导致原有迭代器、指针、引用全部失效,使用时需要特别注意。

优化建议 :提前知道元素数量时,用reserve()预分配容量,避免多次扩容。

五、vector 存放自定义数据类型

vector 不仅能存放基本数据类型,还能存放自定义类、结构体:

cpp 复制代码
#include <string>
// 自定义结构体
struct Student {
    string name;
    int age;
};

int main() {
    vector<Student> v;
    Student s1 = {"张三", 18};
    v.push_back(s1);
    // 访问自定义类型成员
    cout << v[0].name << " " << v[0].age << endl;
    return 0;
}

六、vector 常用算法

配合<algorithm>头文件,可直接使用 STL 算法操作 vector:

cpp 复制代码
#include <algorithm>
vector<int> v = {3,1,4,1,5};

sort(v.begin(), v.end());       // 升序排序
reverse(v.begin(), v.end());    // 反转元素
find(v.begin(), v.end(), 4);    // 查找元素4

七、vector 使用注意事项

  1. 避免在循环中频繁push_back,优先用reserve预分配;
  2. 中间 / 头部插入 / 删除效率低,大量操作时建议用list
  3. 扩容后,旧的迭代器、指针、引用会失效,需要重新获取;
  4. 访问元素优先用[](高效),需要安全检查时用at()
  5. clear()只清空元素,不释放内存,想释放内存用shrink_to_fit()

八、适用场景

  1. 需要随机访问元素(通过下标快速读取);
  2. 元素个数不确定,需要动态扩容
  3. 主要在尾部增删元素;
  4. 替代传统静态数组,简化内存管理。

总结

  1. vector 是连续内存的动态数组,支持随机访问,尾部增删高效;
  2. 核心 API:push_backpop_backinserterasesizecapacity
  3. 区分size(元素个数)和capacity(容量),reserve预分配容量优化性能;
  4. 扩容会成倍分配内存,导致旧迭代器失效;
  5. 是 STL 最常用容器,优先用于动态数组场景。
相关推荐
智者知已应修善业2 小时前
【proteus78进制计数器与非门】2023-7-5
驱动开发·经验分享·笔记·硬件架构·硬件工程
故事和你912 小时前
洛谷-算法2-2-常见优化技巧3
开发语言·数据结构·c++·算法·深度优先·动态规划·图论
foundbug9992 小时前
MATLAB时频分析工具箱:基于FRFT的信号检测与参数估计
开发语言·matlab
DevilSeagull2 小时前
Rust 方法语法:从定义到实践
开发语言·后端·rust
charlie1145141912 小时前
通用GUI编程技术——图形渲染实战(三十七)——D3D11初始化与SwapChain:从零搭建GPU渲染框架
开发语言·c++·3d·图形渲染
陈天伟教授2 小时前
GPT Image 2-城市海报
开发语言·人工智能·gpt·神经网络
原来是猿2 小时前
线程安全的单例模式
linux·服务器·开发语言·单例模式·策略模式
菜鸟555552 小时前
2025江西省CCPC省赛暨全国邀请赛(南昌)
数据结构·c++·算法·acm·思维·ccpc·xcpc
charlie1145141912 小时前
通用GUI编程技术——图形渲染实战(三十六)——Constant Buffer与数据传递:CPU-GPU通信通道
开发语言·c++·windows·c·图形渲染·win32