数组与向量:介绍的相似之处和不同之处

时间:2013-02-26 00:14:47

标签: c++ arrays vector

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

阵列

  

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

     

- C ++ Pocket Reference

矢量

  

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

     

- C ++ Cookbook

3 个答案:

答案 0 :(得分:124)

数组:

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

std::vector

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

还要考虑数组的“现代替代方案” - std::array;我已经在another answer中描述了std::vectorstd::array之间的区别,您可能需要查看它。

答案 1 :(得分:23)

我将补充说,数组是C ++中非常低级的结构,你应该尽量远离它们“学习绳索” - 甚至Bjarne Stroustrup推荐这个(他是C ++的设计者) 。

矢量与阵列的性能非常接近,但具有许多便利性和安全性。在与处理原始数组的API接口时,或者在构建自己的集合时,您可能会开始使用数组。

答案 2 :(得分:9)

这些参考几乎回答了你的问题。简单地说,向量的长度是动态的,而数组具有固定的大小。 使用数组时,请在声明时指定其大小:

int myArray[100];
myArray[0]=1;
myArray[1]=2;
myArray[2]=3;

对于向量,您只需声明它并添加元素

vector<int> myVector;
myVector.push_back(1);
myVector.push_back(2);
myVector.push_back(3);
...

有时你不知道所需元素的数量,因此矢量对于这种情况是理想的。