vector用法 - c++ vector菜鸟教程




数组与矢量:介绍的相似之处和差异 (2)

我会补充说C ++中的数组是非常低级的结构,当“学习”时,应该尽可能地远离它们 - 甚至Bjarne Stroustrup建议这样做(他是C ++的设计者)。

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

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

排列

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

- C ++袖珍参考

向量

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

- C ++食谱


数组:

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

std::vector

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

还要考虑数组的“现代替代” - std::array ; 我已经在另一个回答中描述了std::vectorstd::array之间的区别,你可能想看看它。





vector