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

目录
相关文章
|
3月前
|
人工智能 Java
Java 中数组Array和列表List的转换
本文介绍了数组与列表之间的相互转换方法,主要包括三部分:1)使用`Collections.addAll()`方法将数组转为列表,适用于引用类型,效率较高;2)通过`new ArrayList&lt;&gt;()`构造器结合`Arrays.asList()`实现类似功能;3)利用JDK8的`Stream`流式计算,支持基本数据类型数组的转换。此外,还详细讲解了列表转数组的方法,如借助`Stream`实现不同类型数组间的转换,并附带代码示例与执行结果,帮助读者深入理解两种数据结构的互转技巧。
Java 中数组Array和列表List的转换
|
3月前
|
JavaScript 前端开发 API
JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、复杂API请求、DOM操作、搜索和过滤等,array.map()的使用详解(附实际应用代码)
array.map()可以用来数据转换、创建派生数组、应用函数、链式调用、异步数据流处理、复杂API请求梳理、提供DOM操作、用来搜索和过滤等,比for好用太多了,主要是写法简单,并且非常直观,并且能提升代码的可读性,也就提升了Long Term代码的可维护性。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
4月前
|
算法 编译器 C++
模拟实现c++中的vector模版
模拟实现c++中的vector模版
|
3月前
|
移动开发 运维 供应链
通过array.some()实现权限检查、表单验证、库存管理、内容审查和数据处理;js数组元素检查的方法,some()的使用详解,array.some与array.every的区别(附实际应用代码)
array.some()可以用来权限检查、表单验证、库存管理、内容审查和数据处理等数据校验工作,核心在于利用其短路机制,速度更快,节约性能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
3月前
|
供应链 JavaScript 前端开发
通过array.every()实现数据验证、权限检查和一致性检查;js数组元素检查的方法,every()的使用详解,array.some与array.every的区别(附实际应用代码)
array.every()可以用来数据验证、权限检查、一致性检查等数据校验工作,核心在于利用其短路机制,速度更快,节约性能。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
3月前
|
Web App开发 存储 前端开发
别再用双层遍历循环来做新旧数组对比,寻找新增元素了!使用array.includes和Set来提升代码可读性
这类问题的重点在于能不能突破基础思路,突破基础思路是从程序员入门变成中级甚至高级的第一步,如果所有需求都通过最基础的业务逻辑来做,是得不到成长的。 博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
3月前
|
数据采集 JavaScript 前端开发
JavaScript中通过array.filter()实现数组的数据筛选、数据清洗和链式调用,JS中数组过滤器的使用详解(附实际应用代码)
用array.filter()来实现数据筛选、数据清洗和链式调用,相对于for循环更加清晰,语义化强,能显著提升代码的可读性和可维护性。博客不应该只有代码和解决方案,重点应该在于给出解决方案的同时分享思维模式,只有思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
|
4月前
|
编译器 C++ 开发者
【C++篇】深度解析类与对象(下)
在上一篇博客中,我们学习了C++的基础类与对象概念,包括类的定义、对象的使用和构造函数的作用。在这一篇,我们将深入探讨C++类的一些重要特性,如构造函数的高级用法、类型转换、static成员、友元、内部类、匿名对象,以及对象拷贝优化等。这些内容可以帮助你更好地理解和应用面向对象编程的核心理念,提升代码的健壮性、灵活性和可维护性。
|
13天前
|
人工智能 机器人 编译器
c++模板初阶----函数模板与类模板
class 类模板名private://类内成员声明class Apublic:A(T val):a(val){}private:T a;return 0;运行结果:注意:类模板中的成员函数若是放在类外定义时,需要加模板参数列表。return 0;
|
13天前
|
存储 编译器 程序员
c++的类(附含explicit关键字,友元,内部类)
本文介绍了C++中类的核心概念与用法,涵盖封装、继承、多态三大特性。重点讲解了类的定义(`class`与`struct`)、访问限定符(`private`、`public`、`protected`)、类的作用域及成员函数的声明与定义分离。同时深入探讨了类的大小计算、`this`指针、默认成员函数(构造函数、析构函数、拷贝构造、赋值重载)以及运算符重载等内容。 文章还详细分析了`explicit`关键字的作用、静态成员(变量与函数)、友元(友元函数与友元类)的概念及其使用场景,并简要介绍了内部类的特性。

热门文章

最新文章

下一篇
oss创建bucket