C++中的vector容器详解

C++中的vector容器详解

1. vector概述

vector是C++标准模板库(STL)中最常用的序列容器,提供动态数组功能,能够自动管理内存并在运行时动态调整大小。它在内存中以连续方式存储元素,支持快速随机访问。

2. 基本特性

  • 动态大小:可根据需要自动扩展和收缩
  • 随机访问:支持通过下标直接访问元素
  • 连续存储:元素在内存中连续存放
  • 高效尾部操作:在末尾插入/删除元素效率高
  • 自动内存管理:自动处理内存分配和释放

3. 头文件与声明

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

vector<int> vec1;               // 空vector
vector<string> vec2(5);         // 包含5个默认构造的string
vector<double> vec3(10, 3.14);  // 包含10个3.14
vector<char> vec4{'a', 'b', 'c'}; // 初始化列表
vector<int> vec5(vec4.begin(), vec4.end()); // 范围构造

4. 构造函数与初始化

4.1 默认构造

cpp 复制代码
vector<int> vec;  // 创建空vector

4.2 大小和值构造

cpp 复制代码
vector<string> names(5);        // 5个空字符串
vector<double> prices(8, 9.99); // 8个9.99

4.3 范围构造

cpp 复制代码
int arr[] = {1, 3, 5, 7, 9};
vector<int> odd(arr, arr+5);    // 从数组构造

4.4 拷贝构造

cpp 复制代码
vector<int> vec2(vec1);         // 拷贝构造
vector<int> vec3 = vec1;        // 拷贝赋值

5. 容量操作

5.1 size()

cpp 复制代码
cout << vec.size();  // 返回当前元素数量

5.2 capacity()

cpp 复制代码
cout << vec.capacity();  // 返回当前分配的存储容量

5.3 empty()

cpp 复制代码
if(vec.empty()) {
    cout << "Vector is empty";
}

5.4 max_size()

cpp 复制代码
cout << vec.max_size();  // 返回vector可容纳的最大元素数

5.5 resize()

cpp 复制代码
vec.resize(10);          // 将大小调整为10,新增元素默认初始化
vec.resize(15, 100);     // 将大小调整为15,新增元素初始化为100
vec.resize(5);           // 缩小size,capacity不变

5.6 reserve()

cpp 复制代码
vec.reserve(100);        // 预分配至少能容纳100个元素的空间

5.7 shrink_to_fit()

cpp 复制代码
vec.shrink_to_fit();     // 请求移除未使用的容量

6. 元素访问

6.1 operator[]

cpp 复制代码
vec[2] = 10;             // 修改第3个元素
int val = vec[1];        // 访问第2个元素

6.2 at()

cpp 复制代码
vec.at(3) = 20;          // 修改第4个元素(边界检查)
try {
    int val = vec.at(10); // 抛出std::out_of_range异常
} catch(const out_of_range& e) {
    cerr << e.what() << endl;
}

6.3 front()

cpp 复制代码
vec.front() = 5;         // 修改第一个元素
int first = vec.front(); // 访问第一个元素

6.4 back()

cpp 复制代码
vec.back() = 8;          // 修改最后一个元素
int last = vec.back();   // 访问最后一个元素

6.5 data()

cpp 复制代码
int* p = vec.data();     // 获取指向底层数组的指针
*p = 100;                // 修改第一个元素

7. 修改操作

7.1 push_back()

cpp 复制代码
vec.push_back(42);       // 在末尾添加元素

7.2 emplace_back()

cpp 复制代码
vec.emplace_back(42);    // 在末尾原地构造元素(更高效)

7.3 pop_back()

cpp 复制代码
vec.pop_back();          // 删除最后一个元素

7.4 insert()

cpp 复制代码
vec.insert(vec.begin()+2, 100);          // 在位置2插入100
vec.insert(vec.end(), {5, 6, 7});        // 在末尾插入多个元素
vec.insert(vec.begin(), 3, 9);           // 在开头插入3个9

7.5 emplace()

cpp 复制代码
auto it = vec.emplace(vec.begin()+1, 50); // 在位置1原地构造元素

7.6 erase()

cpp 复制代码
vec.erase(vec.begin()+3);                // 删除位置3的元素
vec.erase(vec.begin(), vec.begin()+2);   // 删除前2个元素

7.7 clear()

cpp 复制代码
vec.clear();             // 清空所有元素(不释放capacity)

7.8 swap()

cpp 复制代码
vector<int> vec2;
vec.swap(vec2);          // 交换两个vector的内容

8. 迭代器

8.1 begin() & end()

cpp 复制代码
for(auto it = vec.begin(); it != vec.end(); ++it) {
    cout << *it << " ";
}

8.2 rbegin() & rend()

cpp 复制代码
for(auto rit = vec.rbegin(); rit != vec.rend(); ++rit) {
    cout << *rit << " ";  // 反向遍历
}

8.3 cbegin() & cend()

cpp 复制代码
for(auto it = vec.cbegin(); it != vec.cend(); ++it) {
    cout << *it << " ";   // const迭代器
}

9. 完整示例

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

int main() {
    // 创建并初始化vector
    vector<int> vec = {2, 3, 1, 7, 5};
    
    // 访问元素
    cout << "First element: " << vec.front() << endl;
    cout << "Last element: " << vec.back() << endl;
    cout << "Element at index 2: " << vec.at(2) << endl;
    
    // 修改元素
    vec[3] = 10;
    vec.at(4) = 20;
    
    // 遍历vector
    cout << "All elements: ";
    for(int num : vec) {
        cout << num << " ";
    }
    cout << endl;
    
    // 使用STL算法
    sort(vec.begin(), vec.end());
    cout << "Sorted vector: ";
    copy(vec.begin(), vec.end(), ostream_iterator<int>(cout, " "));
    cout << endl;
    
    // 添加元素
    vec.push_back(8);
    vec.emplace_back(9);
    vec.insert(vec.begin()+2, 15);
    
    // 删除元素
    vec.pop_back();
    vec.erase(vec.begin()+1);
    
    // 容量信息
    cout << "Size: " << vec.size() << endl;
    cout << "Capacity: " << vec.capacity() << endl;
    cout << "Is empty: " << (vec.empty() ? "Yes" : "No") << endl;
    
    // 调整容量
    vec.reserve(20);
    cout << "After reserve(20), Capacity: " << vec.capacity() << endl;
    vec.shrink_to_fit();
    cout << "After shrink_to_fit(), Capacity: " << vec.capacity() << endl;
    
    return 0;
}

10. 性能提示

  1. 随机访问时间复杂度为O(1)O(1)O(1)
  2. 尾部插入/删除时间复杂度为O(1)O(1)O(1)
  3. 中间/头部插入/删除时间复杂度为O(n)O(n)O(n)
  4. 当空间不足时,重新分配内存会导致所有迭代器失效
  5. reserve()可减少重新分配次数,提高性能

11. 与数组比较

特性 vector 数组
大小 动态可变 固定大小
内存管理 自动管理 手动管理
边界检查 提供at()方法
作为参数传递 不会退化为指针 退化为指针
功能扩展 丰富的方法 基本功能
相关推荐
刻BITTER2 小时前
C++ 获取任意整数类型的最大、最小值和长度
开发语言·c++
程序员老舅2 小时前
C++ STL 算法:从原理到工程实践
linux·c++·stl·c/c++·数据结构与算法
十五年专注C++开发2 小时前
ZeroMQ: 一款高性能、异步、轻量级的消息传输库
网络·c++·分布式·zeroqm
宵时待雨2 小时前
C语言笔记归纳22:预处理详解
c语言·开发语言·笔记
superman超哥2 小时前
仓颉语言中循环语句(for/while)的深度剖析与工程实践
c语言·开发语言·c++·python·仓颉
chenyuhao20242 小时前
Linux系统编程:线程概念与控制
linux·服务器·开发语言·c++·后端
冷雨夜中漫步2 小时前
Java类加载机制——双亲委派与自定义类加载器
java·开发语言·python
weibkreuz2 小时前
模块与组件、模块化与组件化的理解@3
开发语言·前端·javascript
J ..2 小时前
C++ 中的右值引用与移动语义
c++