C++ STL vector 详解:动态数组的利器

vector是C++标准模板库(STL)中最常用的序列容器之一,它提供了动态数组的功能,可以方便地进行元素的添加、删除和访问操作。与普通数组不同,vector的大小是可以动态调整的,因此在使用时不需要提前知道数组的确切大小。

1. vector概述

vector是一个模板类,定义在<vector>头文件中。它的底层实现是一个动态数组,这意味着vector在需要时会自动调整其容量(capacity)以适应新的元素。vector的特点包括:

  • 动态大小vector会自动管理内存,在需要时自动扩展或收缩。
  • 连续存储vector的元素存储在连续的内存块中,这使得vector可以有效地使用指针和偏移量来访问元素。
  • 随机访问vector支持常数时间复杂度的随机访问,类似于C风格数组。

2. 基本使用

在C++中使用vector非常简单,以下是一些常见的操作示例:

#include <iostream>
#include <vector>

int main() {
    // 定义一个存储整数的vector
    std::vector<int> vec;

    // 添加元素
    vec.push_back(10);
    vec.push_back(20);
    vec.push_back(30);

    // 访问元素
    std::cout << "vec[1] = " << vec[1] << std::endl;  // 输出 20

    // 遍历vector
    for (size_t i = 0; i < vec.size(); ++i) {
        std::cout << "vec[" << i << "] = " << vec[i] << std::endl;
    }

    // 删除最后一个元素
    vec.pop_back();

    return 0;
}

常见成员函数

  • push_back(const T& value):在末尾添加元素。
  • pop_back():移除末尾的元素。
  • size():返回当前存储的元素个数。
  • capacity():返回当前分配的容量。
  • resize(size_t n):调整容器大小。
  • clear():清空容器。

3. 底层实现原理

vector的底层实现是一个动态数组。当vector的容量不足以容纳新元素时,它会自动分配一块更大的内存空间,并将现有的元素复制到新内存中。为了减少内存重新分配的次数,vector通常会按照一定的增长策略(例如翻倍)来分配内存。

关键点:

  • 容量与大小size()返回的是当前元素的个数,而capacity()返回的是当前分配的内存可以容纳的元素个数。capacity通常大于或等于size
  • 内存增长策略vector的容量按照一定比例增长,以降低频繁的内存分配开销。常见的增长策略是每次扩展容量为当前的1.5到2倍。
  • 指针失效:由于内存重新分配会导致元素的物理地址变化,因此在向vector中添加或删除元素后,先前的指针或引用可能会失效。

4. 常用操作

插入与删除

除了push_back()pop_back()vector还提供了灵活的插入与删除操作,例如:

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // 插入元素
    vec.insert(vec.begin() + 2, 10);  // 在第3个元素前插入10

    // 删除元素
    vec.erase(vec.begin() + 1);  // 删除第2个元素

    return 0;
}

迭代器

vector提供了标准的迭代器接口,可以方便地进行遍历、插入和删除操作。迭代器包括begin()end()rbegin()rend()等。

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec = {1, 2, 3, 4, 5};

    // 使用正向迭代器遍历
    for (auto it = vec.begin(); it != vec.end(); ++it) {
        std::cout << *it << " ";
    }
    std::cout << std::endl;

    // 使用反向迭代器遍历
    for (auto rit = vec.rbegin(); rit != vec.rend(); ++rit) {
        std::cout << *rit << " ";
    }
    std::cout << std::endl;

    return 0;
}

5. 性能优化建议

尽管vector在大多数情况下表现良好,但仍有一些优化技巧可以帮助提高性能:

  1. 预先分配内存:如果已知vector的最终大小,可以使用reserve()函数预先分配内存以避免多次分配和拷贝。

  2. 避免频繁的插入与删除:由于vector在插入和删除元素时可能会移动大量元素,因此在需要频繁进行插入删除操作时,考虑使用dequelist

  3. 使用shrink_to_fit():在删除大量元素后,可以使用shrink_to_fit()函数来释放不再需要的内存。

#include <iostream>
#include <vector>

int main() {
    std::vector<int> vec(1000, 0);

    // 删除大量元素
    vec.erase(vec.begin(), vec.end() - 100);

    // 收缩容量
    vec.shrink_to_fit();

    return 0;
}

结语

vector作为C++中的一个基础容器类,因其灵活性和高效性被广泛使用。通过了解其底层实现原理和性能特点,可以更好地利用vector,编写出高效、健壮的代码。

希望这篇博客对你深入理解和使用vector有所帮助!

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值