数组 vs 向量:介绍异同 [英] Arrays vs Vectors: Introductory Similarities and Differences

查看:29
本文介绍了数组 vs 向量:介绍异同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C++ 中的数组和向量有什么区别?差异的一个例子可能包括图书馆、象征主义、能力等.

数组

<块引用>

数组包含特定数量的特定类型元素.为了让编译器在编译程序时可以保留所需的空间量,您必须指定数组在定义时将包含的元素的类型和数量.编译器必须能够在编译程序时确定该值.一旦定义了数组,就可以使用数组的标识符和索引来访问数组的特定元素.[...] 数组是零索引的;也就是说,第一个元素在索引 0 处.这种索引方案表明 C++ 中指针和数组之间的密切关系以及该语言为指针算法定义的规则.

——C++袖珍参考

矢量

<块引用>

向量是一个动态大小的对象序列,它提供数组样式的operator[] 随机访问.成员函数 push_back 通过复制构造函数复制其参数,将该副本添加为向量中的最后一项,并将其大小增加 1.pop_back 做的恰恰相反,删除最后一个元素.从向量的末尾插入或删除项目需要分摊常数时间,而从任何其他位置插入或删除需要线性时间.这些是向量的基础知识.他们还有很多.在大多数情况下,向量应该是 C 风格数组的首选.首先,它们是动态调整大小的,这意味着它们可以根据需要增长.您不必像 C 数组那样进行各种研究来找出最佳静态大小;矢量会根据需要增长,如果需要,可以手动调整大小.其次,vectors 提供了使用 at 成员函数的边界检查(但不是使用 operator[]),这样你就可以在引用不存在的索引时做一些事情,而不是简单地观看您的程序崩溃或更糟,使用损坏的数据继续执行.

——C++ 手册

解决方案

数组:

  • 是一个内置的语言结构;
  • 几乎未修改自 C89;
  • 只提供一个连续的、可索引的元素序列;没有花里胡哨;
  • 大小固定;你不能在 C++ 中调整数组的大小(除非它是一个 POD 数组并且它是用 malloc 分配的);
  • 除非它们是动态分配的,否则它们的大小必须是编译时常量;
  • 它们根据您声明它们的范围占用存储空间;
  • 如果是动态分配的,则必须显式释放它们;
  • 如果它们是动态分配的,你只是得到一个指针,你不能确定它们的大小;否则,您可以使用 sizeof(因此是常见的习惯用法 sizeof(arr)/sizeof(*arr),但是当无意中在指针上使用时会默默地失败);
  • 在大多数情况下自动衰减为指针;特别是,当将它们传递给函数时会发生这种情况,这通常需要为它们的大小传递一个单独的参数;
  • 不能从函数返回;
  • 不能直接复制/赋值;
  • 对象的动态数组需要一个默认构造函数,因为必须首先构造它们的所有元素;

std::vector:

  • 是一个模板类;
  • 仅是 C++ 结构;
  • 被实现为一个动态数组
  • 动态增长和收缩;
  • 自动管理它们的内存,在销毁时释放;
  • 可以传递给函数/从函数返回(按值);
  • 可以被复制/分配(这对所有存储的元素执行深度复制);
  • 不会衰减为指针,但您可以显式获取指向其数据的指针(&vec[0] 保证按预期工作);
  • 总是与内部动态数组一起带来它的大小(当前存储了多少元素)和容量(可以存储多少元素> 在当前分配的块中);
  • 内部动态数组不是在对象本身内部分配的(它只包含一些簿记"字段),而是由相关模板参数中指定的分配器动态分配;默认的从 freestore(所谓的堆)获取内存,与实际对象的分配方式无关;
  • 出于这个原因,对于小型、短命的本地数组,它们的效率可能低于常规"数组;
  • 重新分配时,对象被复制(移动,在 C++11 中);
  • 不需要存储对象的默认构造函数;
  • 与所谓的 STL 的其余部分更好地集成(它提供了 begin()/end() 方法,通常的 STL typedefs, ...)

还要考虑数组的现代替代方案" - std::array;我已经在 another answer 中描述了 std 之间的区别::vectorstd::array,你可能想看看.

What are the differences between an array and a vector in C++? An example of the differences might be included libraries, symbolism, abilities, etc.

Array

Arrays contain a specific number of elements of a particular type. So that the compiler can reserve the required amount of space when the program is compiled, you must specify the type and number of elements that the array will contain when it is defined. The compiler must be able to determine this value when the program is compiled. Once an array has been defined, you use the identifier for the array along with an index to access specific elements of the array. [...] arrays are zero-indexed; that is, the first element is at index 0. This indexing scheme is indicative of the close relationship in C++ between pointers and arrays and the rules that the language defines for pointer arithmetic.

— C++ Pocket Reference

Vector

A vector is a dynamically-sized sequence of objects that provides array-style operator[] random access. The member function push_back copies its arguments via copy constructor, adds that copy as the last item in the vector and increments its size by one. pop_back does the exact opposite, by removing the last element. Inserting or deleting items from the end of a vector takes amortized constant time, and inserting or deleting from any other location takes linear time. These are the basics of vectors. There is a lot more to them. In most cases, a vector should be your first choice over a C-style array. First of all, they are dynamically sized, which means they can grow as needed. You don't have to do all sorts of research to figure out an optimal static size, as in the case of C arrays; a vector grows as needed, and it can be resized larger or smaller manually if you need to. Second, vectors offer bounds checking with the at member function (but not with operator[]), so that you can do something if you reference a nonexistent index instead of simply watching your program crash or worse, continuing execution with corrupt data.

— C++ Cookbook

解决方案

arrays:

  • are a builtin language construct;
  • come almost unmodified from C89;
  • provide just a contiguous, indexable sequence of elements; no bells and whistles;
  • are of fixed size; you can't resize an array in C++ (unless it's an array of POD and it's allocated with malloc);
  • their size must be a compile-time constant unless they are allocated dynamically;
  • they take their storage space depending from the scope where you declare them;
  • if dynamically allocated, you must explicitly deallocate them;
  • if they are dynamically allocated, you just get a pointer, and you can't determine their size; otherwise, you can use sizeof (hence the common idiom sizeof(arr)/sizeof(*arr), that however fails silently when used inadvertently on a pointer);
  • automatically decay to a pointers in most situations; in particular, this happens when passing them to a function, which usually requires passing a separate parameter for their size;
  • can't be returned from a function;
  • can't be copied/assigned directly;
  • dynamical arrays of objects require a default constructor, since all their elements must be constructed first;

std::vector:

  • is a template class;
  • is a C++ only construct;
  • is implemented as a dynamic array;
  • grows and shrinks dynamically;
  • automatically manage their memory, which is freed on destruction;
  • can be passed to/returned from functions (by value);
  • can be copied/assigned (this performs a deep copy of all the stored elements);
  • doesn't decay to pointers, but you can explicitly get a pointer to their data (&vec[0] is guaranteed to work as expected);
  • always brings along with the internal dynamic array its size (how many elements are currently stored) and capacity (how many elements can be stored in the currently allocated block);
  • the internal dynamic array is not allocated inside the object itself (which just contains a few "bookkeeping" fields), but is allocated dynamically by the allocator specified in the relevant template parameter; the default one gets the memory from the freestore (the so-called heap), independently from how where the actual object is allocated;
  • for this reason, they may be less efficient than "regular" arrays for small, short-lived, local arrays;
  • when reallocating, the objects are copied (moved, in C++11);
  • does not require a default constructor for the objects being stored;
  • is better integrated with the rest of the so-called STL (it provides the begin()/end() methods, the usual STL typedefs, ...)

Also consider the "modern alternative" to arrays - std::array; I already described in another answer the difference between std::vector and std::array, you may want to have a look at it.

这篇关于数组 vs 向量:介绍异同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆