C++ Vector 全解析:从使用到深入理解

目录

[一、Vector 是什么?](#一、Vector 是什么?)

[二、Vector 的基本使用](#二、Vector 的基本使用)

[2.1 构造与初始化](#2.1 构造与初始化)

[2.2 迭代器使用](#2.2 迭代器使用)

[2.3 容量操作](#2.3 容量操作)

[三、Vector 的增删查改](#三、Vector 的增删查改)

[3.1 基本操作](#3.1 基本操作)

四、迭代器失效问题(重点!)

[4.1 导致迭代器失效的操作](#4.1 导致迭代器失效的操作)

[4.2 错误示例](#4.2 错误示例)

[4.3 正确做法](#4.3 正确做法)

[五、Vector 在算法题中的应用](#五、Vector 在算法题中的应用)

[5.1 只出现一次的数字(异或技巧)](#5.1 只出现一次的数字(异或技巧))

[5.2 杨辉三角](#5.2 杨辉三角)

[六、Vector 的模拟实现注意事项](#六、Vector 的模拟实现注意事项)

[6.1 深拷贝问题](#6.1 深拷贝问题)

[6.2 动态二维数组](#6.2 动态二维数组)

七、实战练习建议

八、总结


一、Vector 是什么?

vector 是 C++ 标准模板库(STL)中的一个动态数组容器,它能够根据需要自动调整大小,支持快速随机访问,是 C++ 中最常用的容器之一。

二、Vector 的基本使用

2.1 构造与初始化

cpp

复制代码
#include <vector>
using namespace std;

vector<int> v1;               // 空vector
vector<int> v2(5, 10);        // 5个元素,每个都是10
vector<int> v3(v2);           // 拷贝构造
vector<int> v4(v3.begin(), v3.end()); // 迭代器范围构造

2.2 迭代器使用

cpp

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

// 正向迭代
for (auto it = v.begin(); it != v.end(); ++it) {
    cout << *it << " ";
}

// 反向迭代
for (auto it = v.rbegin(); it != v.rend(); ++it) {
    cout << *it << " ";
}

2.3 容量操作

cpp

复制代码
vector<int> v;
cout << v.size();      // 元素个数
cout << v.capacity();  // 当前容量
cout << v.empty();     // 是否为空

v.reserve(100);        // 预留至少100个元素的空间
v.resize(50);          // 调整大小为50,多出的用默认值填充

注意 :不同编译器下 vector 的扩容策略不同:

  • VS 下按 1.5 倍增长

  • g++ 下按 2 倍增长

三、Vector 的增删查改

3.1 基本操作

cpp

复制代码
vector<int> v;

// 增
v.push_back(10);            // 尾插
v.insert(v.begin(), 5);     // 在指定位置插入

// 删
v.pop_back();               // 尾删
v.erase(v.begin());         // 删除指定位置
v.clear();                  // 清空

// 查
auto it = find(v.begin(), v.end(), 10); // 查找元素
if (it != v.end()) {
    cout << "找到了";
}

// 改
v[0] = 100;                 // 像数组一样访问

四、迭代器失效问题(重点!)

迭代器失效是使用 vector 时最容易出错的问题之一。简单说,就是当 vector 发生某些操作后,之前获取的迭代器指向的内存可能已经无效。

4.1 导致迭代器失效的操作

  1. 扩容操作push_backresizereserveinsert 等可能导致扩容

  2. 删除操作erase 删除元素

  3. 赋值操作assign

4.2 错误示例

cpp

复制代码
vector<int> v = {1, 2, 3, 4};
auto it = v.begin();

v.push_back(5);  // 可能导致扩容,it失效!

// 错误!it可能指向已释放的内存
while (it != v.end()) {
    cout << *it << " ";
    ++it;
}

4.3 正确做法

cpp

复制代码
// 删除所有偶数 - 正确写法
vector<int> v = {1, 2, 3, 4, 5};
auto it = v.begin();
while (it != v.end()) {
    if (*it % 2 == 0) {
        it = v.erase(it);  // erase返回下一个有效迭代器
    } else {
        ++it;
    }
}

五、Vector 在算法题中的应用

5.1 只出现一次的数字(异或技巧)

cpp

复制代码
int singleNumber(vector<int>& nums) {
    int value = 0;
    for (auto e : nums) {
        value ^= e;  // 利用 a^a=0 的特性
    }
    return value;
}

5.2 杨辉三角

cpp

复制代码
vector<vector<int>> generate(int numRows) {
    vector<vector<int>> vv(numRows);
    for (int i = 0; i < numRows; ++i) {
        vv[i].resize(i + 1, 1);  // 每行初始化为1
        for (int j = 1; j < i; ++j) {
            vv[i][j] = vv[i-1][j] + vv[i-1][j-1];
        }
    }
    return vv;
}

六、Vector 的模拟实现注意事项

6.1 深拷贝问题

在模拟实现 vector 时,reserve 中不能使用 memcpy 来拷贝元素,尤其是元素类型涉及资源管理(如 string)时:

cpp

复制代码
// 错误!浅拷贝会导致问题
void reserve(size_t n) {
    // ...
    memcpy(_newStart, _start, sizeof(T) * size());  // 危险!
}

// 正确做法:使用循环赋值,调用元素的拷贝构造
for (size_t i = 0; i < size(); ++i) {
    _newStart[i] = _start[i];  // 调用T的operator=或拷贝构造
}

6.2 动态二维数组

cpp

复制代码
// 创建n行的二维数组
vector<vector<int>> vv(n);

// 每行设置不同大小
for (int i = 0; i < n; ++i) {
    vv[i].resize(i + 1, 1);
}

七、实战练习建议

  1. 基础操作 :熟练掌握 push_backpop_backoperator[]size 等常用接口

  2. 迭代器理解:理解迭代器失效的原因及解决方案

  3. OJ练习

    • 删除排序数组中的重复项

    • 只出现一次的数字 II/III

    • 数组中出现次数超过一半的数字

    • 电话号码字母组合

八、总结

vector 是 C++ 中最实用、最高效的容器之一,掌握它需要:

  • 理解其底层是动态数组

  • 熟悉常用接口的使用场景

  • 特别注意迭代器失效问题

  • 了解不同编译器下的扩容策略差异

通过理论学习和实际编码练习相结合,你一定能熟练掌握 vector,为后续的 C++ 学习和开发打下坚实基础!

相关推荐
秋邱2 小时前
Java数组与二维数组:创建、初始化、遍历与实操案例全解析
java·开发语言
Dream it possible!2 小时前
LeetCode 面试经典 150_分治_将有序数组转换为二叉搜索树(105_108_C++_简单)(递归)
c++·leetcode·面试
Q741_1472 小时前
C++ 栈 模拟 力扣 227. 基本计算器 II 题解 每日一题
c++·算法·leetcode·模拟
徐新帅2 小时前
CSP 二进制与小数进制转换专题及答案解析
c++·算法
wangxingps2 小时前
phpmyadmin版本对应的各php版本
服务器·开发语言·php
charlee442 小时前
Git使用经验总结9-Git提交关联到Issue
git·issue
独自破碎E2 小时前
消息队列如何处理重复消息?
java·开发语言·rocketmq
im_AMBER2 小时前
Leetcode 88 K 和数对的最大数目
数据结构·c++·笔记·学习·算法·leetcode
兵哥工控2 小时前
MFC分组平均法数据平滑曲线实例
c++·mfc