【C/C++ 基础 数组容器比较】深入探究C++容器:数组、vector与array之间的异同

简介: 【C/C++ 基础 数组容器比较】深入探究C++容器:数组、vector与array之间的异同
数组 vector array
访问方式 支持标准访问 支持标准访问
存储位置
复制 逐个复制

共同点

  1. vector和array是容器;
  2. 三者均可以使用下表运算符对元素进行操作,即vector和array都针对下标运算符[]进行了重载;
  3. 三者在内存的方面都使用连续内存,即在vector和array的底层存储结构均使用数组

不同点

(0.)安全性:数组是不安全的,array和vector是比较安全的(有效的避免越界等问题)

(1.)存储位置部分:std::array是在栈区分配的,它的大小在编译时已经确定,vector对象存储在堆区。数组可以存储在栈上(自动分配的数组)或堆上(使用new[]或malloc()分配的数组)。

(2.)复制部分:数组需要逐个元素复制,vector和array可以使用拷贝构造函数或赋值操作符实现整个对象的复制。

(3.)vector属于变长的容器,即可以根据数据的插入和删除重新构造容器容量;但是array和数组属于定长容器

(4.)vector提供了front()和back()以及at()访问方式,array提供了at()访问方式,使得访问更加安全。可以避免a[-1]访问越界的问题访问方式,使得访问更加安全。而数组只能通过下标访问,在写程序中很容易出现越界的错误

(5.)vector和array提供了更好的遍历机制,即有正向迭代器和反向迭代器,数组支持指针作为迭代器进行遍历,但不提供反向迭代器。

(6.)vector和array提供了size()和Empty(),而数组只能通过sizeof()/strlen()以及遍历计数来获取大小和是否为空(使用strlen()获取数组大小只适用于字符数组。对于其他类型的数组,您需要手动计算数组长度

(7.)vector和array提供了两个容器对象的内容交换,即swap()的机制,而数组对于交换只能通过遍历的方式逐个交换元素

(8.)array提供了初始化所有成员的方法fill()

(9.)由于vector的动态内存变化的机制,在插入和删除时,需要考虑迭代的是否有效问题

(10.)vector和array在声明变量后,在声明周期完成后,会自动地释放其所占用的内存。对于数组如果用new[ ]/malloc申请的空间,必须用对应的delete[ ]和free来释放内存

性能比较

在许多情况下,数组、`std::array`和`std::vector`的性能差异可能并不明显,但在某些特定的使用场景下,它们的性能差异可能会变得非常显著。以下是一些关于这三者性能比较的观察:

  • **1. 内存分配:**

数组和`std::array`在编译时确定大小,因此它们的内存分配是静态的,这意味着它们在内存分配上的开销较小。相比之下,`std::vector`是动态分配内存的,当需要增加或减少元素时,可能需要重新分配内存,这可能导致更大的内存开销。

  • **2. 插入和删除元素:**

对于数组和`std::array`,插入和删除元素通常需要移动大量元素,这可能会导致较大的性能开销。相比之下,`std::vector`在尾部插入和删除元素的性能非常高效,但在中间或头部插入和删除元素可能需要移动大量元素,这可能导致较大的性能开销。

  • **3. 访问元素:**

数组、`std::array`和`std::vector`都支持通过下标访问元素,这是非常高效的。然而,`std::vector`和`std::array`还提供了额外的成员函数,如`at()`,这些函数在提供范围检查的同时可能会有一些额外的开销。

  • **4. 内存占用:**

由于`std::vector`需要存储额外的信息,如容量,因此它可能会占用比数组和`std::array`更多的内存。然而,这通常只在元素数量非常大时才会成为问题。

  • **5. 缓存友好性:**

由于数组、`std::array`和`std::vector`都使用连续的内存,因此它们都非常适合现代硬件的缓存系统,这可以显著提高性能。

总的来说,选择使用数组、`std::array`还是`std::vector`,应该根据具体的使用场景和需求来决定。在许多情况下,`std::vector`由于其灵活性和易用性,可能是一个更好的选择。然而,在对性能有严格要求的情况下,可能需要更仔细地考虑这三者的性能差异。

结语

**<font face="楷体" color=#984229 size =3>在我们的编程学习之旅中,理解是我们迈向更高层次的重要一步。然而,掌握新技能、新理念,始终需要时间和坚持。从心理学的角度看,学习往往伴随着不断的试错和调整,这就像是我们的大脑在逐渐优化其解决问题的“算法”。</font>**

**<font face="楷体" color=#15427 size =3>这就是为什么当我们遇到错误,我们应该将其视为学习和进步的机会,而不仅仅是困扰。通过理解和解决这些问题,我们不仅可以修复当前的代码,更可以提升我们的编程能力,防止在未来的项目中犯相同的错误。</font>**

**<font face="楷体" color=#9999 size =3>我鼓励大家积极参与进来,不断提升自己的编程技术。无论你是初学者还是有经验的开发者,我希望我的博客能对你的学习之路有所帮助。如果你觉得这篇文章有用,不妨点击收藏,或者留下你的评论分享你的见解和经验,也欢迎你对我博客的内容提出建议和问题。每一次的点赞、评论、分享和关注都是对我的最大支持,也是对我持续分享和创作的动力。

目录
相关文章
|
存储 C++ 容器
如何将没有复制或移动构造函数的对象放入vector容器
如何将没有复制或移动构造函数的对象放入vector容器
265 0
|
存储 缓存 C++
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
C++ 标准模板库(STL)提供了一组功能强大的容器类,用于存储和操作数据集合。不同的容器具有独特的特性和应用场景,因此选择合适的容器对于程序的性能和代码的可读性至关重要。对于刚接触 C++ 的开发者来说,了解这些容器的基础知识以及它们的特点是迈向高效编程的重要一步。本文将详细介绍 C++ 常用的容器,包括序列容器(`std::vector`、`std::array`、`std::list`、`std::deque`)、关联容器(`std::set`、`std::map`)和无序容器(`std::unordered_set`、`std::unordered_map`),全面解析它们的特点、用法
1015 1
C++ 容器全面剖析:掌握 STL 的奥秘,从入门到高效编程
|
存储 搜索推荐 C++
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
365 9
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器2
|
存储 C++ 容器
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器1
【C++篇】深度剖析C++ STL:玩转 list 容器,解锁高效编程的秘密武器
385 5
|
存储 编译器 C++
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
【C++篇】揭开 C++ STL list 容器的神秘面纱:从底层设计到高效应用的全景解析(附源码)
371 2
|
存储 对象存储 C++
C++ 中 std::array<int, array_size> 与 std::vector<int> 的深入对比
本文深入对比了 C++ 标准库中的 `std::array` 和 `std::vector`,从内存管理、性能、功能特性、使用场景等方面详细分析了两者的差异。`std::array` 适合固定大小的数据和高性能需求,而 `std::vector` 则提供了动态调整大小的灵活性,适用于数据量不确定或需要频繁操作的场景。选择合适的容器可以提高代码的效率和可靠性。
|
存储 设计模式 C++
【C++】优先级队列(容器适配器)
本文介绍了C++ STL中的线性容器及其适配器,包括栈、队列和优先队列的设计与实现。详细解析了`deque`的特点和存储结构,以及如何利用`deque`实现栈、队列和优先队列。通过自定义命名空间和类模板,展示了如何模拟实现这些容器适配器,重点讲解了优先队列的内部机制,如堆的构建与维护方法。
295 0
|
C++ 容器
【C++航海王:追寻罗杰的编程之路】关联式容器的底层结构——AVL树
【C++航海王:追寻罗杰的编程之路】关联式容器的底层结构——AVL树
248 5
|
存储 C++ 索引
【C++】关联容器
【C++】关联容器
【C++】关联容器
|
存储 C++ 容器
开发与运维数组问题之C++标准库中提供数据容器作为数组的替代如何解决
开发与运维数组问题之C++标准库中提供数据容器作为数组的替代如何解决
243 5