vector容器的初认识

vector 是 C++ 标准库(STL)提供的动态数组容器,本质是对「原生动态数组(new[]/delete[])」的封装,核心优势是 自动管理内存(无需手动 new/delete)、支持动态扩容、提供丰富的成员函数,比原生动态数组更安全、更易用。

一、vector 核心优势(为什么用 vector?)

对比之前的原生动态数组,vector 解决了三大痛点:

  1. 无需手动管理内存(自动分配 / 扩容 / 释放,避免内存泄漏)
  2. 内置 size() 成员函数,直接获取数组长度(无需手动记录 n);
  3. 支持动态添加 / 删除元素(push_back()/pop_back()),长度可灵活调整;
  4. 兼容原生数组的访问方式(下标 / 指针),学习成本低。

二、vector 基础用法(四步走)

步骤 1:包含头文件 + 命名空间

vector 定义在 <vector> 头文件中,需提前包含:

#include <iostream>
#include <vector>  // 必须包含 vector 头文件
using namespace std;  // 简化命名,避免写 std::vector
步骤 2:创建 vector(初始化方式)

vector 是模板类,创建时需指定元素类型(如 intchar),支持多种初始化方式,按需选择:

初始化方式语法示例说明
空 vector(默认)vector<int> vec;创建空的 int 类型 vector,初始长度为 0
指定长度(默认初始化)vector<int> vec(5);长度为 5,元素默认值为 0(int 类型)
指定长度 + 初始值vector<int> vec(5, 10);长度为 5,所有元素初始化为 10([10,10,10,10,10])
列表初始化(C++11+)vector<int> vec = {1,2,3,4,5};直接用列表赋值,长度自动为 5
拷贝初始化vector<int> vec2(vec1);用 vec1 的元素拷贝创建 vec2(完全独立)

示例:

vector<int> vec1;                // 空 vector(size=0)
vector<int> vec2(3);             // [0, 0, 0](size=3)
vector<int> vec3(3, 6);          // [6, 6, 6](size=3)
vector<int> vec4 = {2,4,6,8};    // [2,4,6,8](size=4)
vector<int> vec5(vec4);          // 拷贝 vec4 → [2,4,6,8]
步骤 3:vector 核心操作(赋值 / 访问 / 增删)

vector 支持「下标访问」和「成员函数访问」,以下是最常用的操作:

1. 赋值与访问元素
  • 下标访问:和原生数组一致(vec[i]),但不检查下标越界(越界会崩溃);
  • at(i) 访问:检查下标越界(越界会抛异常),更安全;
  • 遍历方式:循环下标、迭代器(推荐)、范围 for(C++11+,最简洁)。

示例:

vector<int> vec = {10,20,30};

// 1. 赋值(下标)
vec[0] = 100;  // vec 变为 [100,20,30]
vec.at(1) = 200;  // vec 变为 [100,200,30](安全访问)

// 2. 遍历方式 1:循环下标(适合需要索引的场景)
cout << "遍历方式 1(下标):";
for (int i = 0; i < vec.size(); i++) {
    cout << vec[i] << " ";  // 输出:100 200 30
}
cout << endl;

// 3. 遍历方式 2:范围 for(C++11+,最简洁,无需索引)
cout << "遍历方式 2(范围 for):";
for (int x : vec) {
    cout << x << " ";  // 输出:100 200 30
}
cout << endl;

// 4. 遍历方式 3:迭代器(STL 标准方式,兼容所有容器)
cout << "遍历方式 3(迭代器):";
for (vector<int>::iterator it = vec.begin(); it != vec.end(); it++) {
    cout << *it << " ";  // *it 访问迭代器指向的元素
}
cout << endl;
2. 动态增删元素

vector 最强大的功能是动态调整长度,核心函数:

  • push_back(x):在数组末尾添加元素 x(自动扩容);
  • pop_back():删除数组末尾元素(长度减 1,不释放内存);
  • clear():清空所有元素(长度变为 0,不释放内存);
  • empty():判断是否为空(size()==0 等价,但更高效)。

示例:

vector<int> vec;

// 添加元素(push_back)
vec.push_back(1);  // [1](size=1)
vec.push_back(2);  // [1,2](size=2)
vec.push_back(3);  // [1,2,3](size=3)

// 删除末尾元素(pop_back)
vec.pop_back();    // [1,2](size=2)

// 判断是否为空
if (!vec.empty()) {
    cout << "当前 vector:";
    for (int x : vec) cout << x << " ";  // 输出:1 2
}

// 清空元素
vec.clear();       // 空 vector(size=0)
cout << "\n清空后 size:" << vec.size();  // 输出:0
3. 获取长度与容量
  • size():返回当前元素个数(实际存储的元素数);
  • capacity():返回当前分配的内存容量(能容纳的最大元素数,扩容时会翻倍)。

示例:

vector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);

cout << "size:" << vec.size();     // 3(实际有 3 个元素)
cout << "capacity:" << vec.capacity();  // 通常是 4(不同编译器可能不同,扩容策略是翻倍)
步骤 4:释放 vector 内存(可选)

vector 会在生命周期结束时自动释放内存(比如函数返回、main 结束),无需手动释放,避免了原生动态数组的内存泄漏问题。

若需手动释放内存(比如 vector 占用过大,想提前回收),可使用「swap 技巧」:

vector<int> vec(1000, 10);  // 占用较大内存
vec.swap(vector<int>());    // 与空 vector 交换,原内存被释放
cout << "size:" << vec.size();     // 0
cout << "capacity:" << vec.capacity();  // 0

三、vector 与原生动态数组对比(关键区别)

特性vector(容器)原生动态数组(new[]
内存管理自动分配 / 扩容 / 释放(无泄漏风险)手动 new[]/delete[](易漏释放)
长度获取size() 直接获取(安全)需手动记录 n(易出错)
动态调整长度push_back()/pop_back() 直接支持需重新分配内存 + 拷贝元素(复杂)
下标越界检查at(i) 支持(安全),[] 不支持不支持(越界直接崩溃)
易用性高(成员函数丰富)低(需手动处理所有细节)

结论:日常开发中,优先用 vector 替代原生动态数组,除非有特殊底层优化需求。

四、实战示例:用 vector 实现「找最大 / 最小值」

结合你之前的需求,用 vector 重写找最大 / 最小值的程序,对比原生动态数组更简洁安全:

#include <iostream>
#include <vector>
using namespace std;

// 函数参数:vector<int>&(引用传递,避免拷贝,效率高)
void findMaxMin(const vector<int>& vec) {
    if (vec.empty()) {  // 边界处理:空 vector
        cout << "vector 为空!" << endl;
        return;
    }

    int max_val = vec[0];
    int min_val = vec[0];

    // 范围 for 遍历(简洁)
    for (int x : vec) {
        if (x > max_val) max_val = x;
        if (x < min_val) min_val = x;
    }

    cout << "max = " << max_val << endl;
    cout << "min = " << min_val << endl;
}

int main() {
    int n;
    cout << "请输入元素个数:";
    cin >> n;

    vector<int> vec(n);  // 创建长度为 n 的 vector
    cout << "请输入 " << n << " 个整数:";
    for (int i = 0; i < n; i++) {
        cin >> vec[i];  // 下标赋值
    }

    findMaxMin(vec);  // 直接传入 vector(引用传递)

    // 无需手动释放内存(vector 生命周期结束自动释放)
    return 0;
}
运行效果:

plaintext

请输入元素个数:5
请输入 5 个整数:3 1 4 2 5
max = 5
min = 1

五、vector 常见误区与避坑

1. 下标越界访问
  • 错误:vector<int> vec(3); vec[5] = 10;(下标 5 超出 size=3);
  • 后果:程序崩溃(未定义行为);
  • 解决:用 at(i) 访问(越界会抛异常,便于调试),或访问前检查 i < vec.size()
2. 混淆 size() 和 capacity()
  • size() 是实际元素个数,capacity() 是当前内存能容纳的最大元素数;
  • 例如:vec.push_back(1) 后,size=1capacity 可能是 2(编译器默认扩容策略);
  • 误区:认为 capacity() 等于 size(),导致误判内存占用。
3. 频繁 push_back() 导致扩容开销
  • vector 扩容时会:分配新内存 → 拷贝旧元素 → 释放旧内存(有性能开销);
  • 优化:提前用 reserve(n) 预留容量(避免频繁扩容),比如已知要存 1000 个元素:
    vector<int> vec;
    vec.reserve(1000);  // 提前预留 1000 个元素的容量
    for (int i = 0; i < 1000; i++) {
        vec.push_back(i);  // 无扩容开销,效率更高
    }
    

总结

vector 是 C++ 最常用的容器,核心是「自动内存管理 + 动态扩容 + 易用性」,基础用法可总结为:

  1. 包含 <vector> 头文件;
  2. 用合适的方式初始化 vector
  3. 用 []/at() 访问元素,用 push_back()/pop_back() 增删元素;
  4. 用 size() 获取长度,无需手动释放内存。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值