知识总结Vector | 豆包MarsCode AI 刷题

124 阅读6分钟

一、基础知识

定义与初始化

  1. 基本定义方式
    vector 是 C++ 标准模板库(STL)中的一个动态大小数组容器,它可以在运行时根据需要自动调整大小,能方便地存储和操作同类型的元素序列。例如,定义一个存储 int 类型元素的 vector,可以使用以下方式:
#include <vector>
using namespace std;

vector<int> myVector; // 定义一个空的int类型vector
  1. 初始化列表初始化
    可以在定义时使用初始化列表来为 vector 赋初值,像这样:
vector<int> myVector = {1, 2, 3, 4, 5}; // 初始化为包含5个整数元素的vector
  1. 指定大小初始化
    还能指定 vector 的初始大小以及默认的初始元素值(如果有的话)。例如,创建一个包含 10 个初始值为 0 的 int 类型元素的 vector
vector<int> myVector(10, 0); // 大小为10,每个元素初始化为0

(二)元素访问

  1. 通过下标访问
    和普通数组一样,vector 支持使用下标运算符 [] 来访问元素,下标从 0 开始。例如:
vector<int> myVector = {1, 2, 3, 4, 5}; 
cout << myVector[2] << endl; // 输出第3个元素,即3

但需要注意的是,使用 [] 访问时要确保下标不超出 vector 当前的有效范围,否则会导致未定义行为(比如程序崩溃或者出现错误结果)。 2. 使用 at() 方法访问
vector 提供了 at() 方法来更安全地访问元素,它会进行边界检查,如果下标越界,会抛出 out_of_range 异常,而不是像 [] 那样直接导致错误。例如:

try { 
    vector<int> myVector = {1, 2, 3, 4, 5}; 
    cout << myVector.at(10) << endl; // 这里下标10超出范围,会抛出异常 
} catch (out_of_range& e) { 
    cerr << "下标越界异常: " << e.what() << endl; 
}

(三)添加和删除元素

  1. push_back() 方法添加元素
    这是最常用的向 vector 末尾添加元素的方法。每次调用 push_back(),都会在 vector 的尾部插入一个新元素,并且 vector 会自动调整大小以容纳新元素。例如:
vector<int> myVector;
myVector.push_back(1);
myVector.push_back(2); // 此时myVector包含两个元素,分别是1和2
  1. pop_back() 方法删除元素
    用于删除 vector 的最后一个元素,它会直接移除末尾元素,并且 vector 的大小会减 1。例如:
vector<int> myVector = {1, 2, 3};
myVector.pop_back(); // 此时myVector变为{1, 2}
  1. 插入和删除指定位置的元素
    可以使用 insert() 方法在指定位置插入一个或多个元素,以及使用 erase() 方法删除指定位置的元素。例如:
vector<int> myVector = {1, 2, 4, 5}; // 在第2个位置(下标为1)插入元素3 
myVector.insert(myVector.begin() + 1, 3); // 删除第3个位置(下标为2)的元素 
myVector.erase(myVector.begin() + 2); // 此时myVector变为{1, 3, 5}

二、个人理解

(一)优势与便利性

vector 在 C++ 编程中是一个非常强大且实用的工具,它解决了传统数组在大小固定方面的局限性。在编写程序时,我们常常无法提前确定需要存储的数据量到底有多少,vector 就能根据实际情况动态地调整大小,让代码的编写更加灵活,不用担心数组越界导致内存访问错误等问题(当然,前提是正确使用边界检查方法)。比如在处理用户输入的数据列表、动态生成的数据集合等场景中,vector 可以轻松应对,大大简化了编程过程。

(二)内存管理机制

它的内存管理机制也很有意思,vector 内部会自动处理内存的分配和重新分配,当添加元素使得当前元素个数超过容量时,它会申请新的更大的内存空间,并将原有元素复制或移动到新空间中,这个过程虽然会有一定的性能开销,但对于开发者来说,无需手动去管理这些复杂的内存操作,降低了内存管理出错的风险,使得我们可以更专注于业务逻辑的实现。

(三)与其他容器的比较

和 C++ 中的其他容器(如 listdeque 等)相比,vector 的优势在于它提供了类似数组的快速随机访问能力(通过下标访问元素速度很快),这在需要频繁根据索引获取元素的场景中表现出色。然而,在频繁的头部或中间位置插入和删除元素时,由于涉及到后续元素的移动,相对来说效率可能不如 list 等链表结构的容器,但如果插入和删除操作主要集中在末尾(比如常见的顺序添加元素然后一次性处理的情况),vector 依然是一个很好的选择。

三、对入门同学的学习建议

(一)多实践多练习

对于刚接触 C++ 和 vector 的同学来说,一定要多动手写代码进行练习。可以通过自己编写一些简单的小程序,比如实现一个简单的学生成绩管理系统,用 vector 来存储学生的成绩数据,进行添加、删除、查询等操作,通过实际的编程体验来熟悉 vector 的各种方法的使用,只有在实践中才能真正理解每个操作的效果以及可能出现的问题,比如下标越界、内存分配变化等情况。

(二)理解内存相关概念

尽管 vector 帮我们自动管理了很多内存方面的事情,但了解其背后的内存管理机制对于深入理解 vector 以及避免一些潜在的性能问题是很有帮助的。可以学习一下数组在内存中的存储方式、动态内存分配的基本原理等知识,这样在使用 vector 时就能明白为什么有时候插入大量元素会有性能损耗,以及如何合理地预估初始容量等操作来优化性能。

(三)对比学习不同容器

不要孤立地学习 vector,可以将它与 C++ 中的其他容器(如前面提到的 listdeque 等)进行对比学习。了解它们各自的特点、适用场景以及优缺点,这样在实际编程遇到问题时,就能根据具体的需求快速选择最合适的容器来存储和处理数据。比如,在需要频繁在中间位置插入和删除元素并且对随机访问性能要求不高的场景下,就可以考虑使用 list 而不是 vector

(四)参考优秀代码和文档

阅读一些优秀的 C++ 开源代码或者官方文档中关于 vector 的示例代码,学习别人是如何正确、高效地使用 vector 的。官方文档通常会详细解释每个方法的参数、返回值以及各种使用注意事项,是非常权威的学习资料。同时,开源代码中能看到 vector 在实际项目中的应用场景和使用方式,有助于拓宽自己的编程思路,提升对 vector 的运用能力。

总之,vector 是 C++ 中一个重要且实用的知识点,通过不断学习、实践和对比分析,入门同学可以逐渐掌握它并灵活运用到自己的编程项目中,为后续深入学习 C++ 编程打下坚实的基础。