是否有正当理由在C ++中使用C风格的数组?

时间:2014-10-12 16:12:59

标签: c++ arrays

在TR1和C ++ 11中的std::vectorstd::array之间,对于动态和固定大小的数组都有安全的替代方案,这些数组知道自己的长度并且不会出现可怕的指针/数组二元性。

所以我的问题是,当C阵列必须必须时,C ++中是否存在任何情况(除了调用C库代码之外),或者"禁止"他们一共?

修改

感谢所有人的回复,但事实证明这个问题是

的重复

Now that we have std::array what uses are left for C-style arrays?

所以我会引导所有人去看那里。

[我不确定如何关闭我自己的问题,但如果主持人(或更多有投票的人)徘徊过去,请随意将其标记为复制并删除此句子。] < / p>

8 个答案:

答案 0 :(得分:2)

我一开始并不想回答这个问题,但我已经开始担心这个问题会被C程序员或者将C ++编写为面向对象C的人所淹没。

真正的答案是,在惯用的C ++中,几乎从来没有理由使用C风格的数组。即使使用C风格的代码库,我通常也会使用向量。你说怎么可能呢?好吧,如果你有一个向量v和一个C风格的函数需要传入一个指针,你可以传递&amp; v [0](或者更好的是,v.data()这是同样的事情。)

即使是性能,也很少能为C风格数组提供一个案例。 std :: vector确实涉及双间接,但我相信这通常是优化的。如果你不相信编译器(这几乎总是一个糟糕的举动),那么你总是可以使用与上面相同的技术与v.data()来获取紧密循环的指针。对于std :: array,我相信包装器更薄。

如果你是一个很棒的程序员而且你确切知道为什么要这样做,或者如果一个很棒的程序员看着你的问题并告诉你,你应该只使用一个。如果你不是很棒并且你正在使用C风格的数组,那么你犯错误的可能性很高(但不是100%),

答案 1 :(得分:2)

Foo data[] = {

是一种非常常见的模式。元素可以很容易地添加到它,data数组的大小会根据添加的元素增加。

使用C ++ 11,您可以使用std::array

复制此内容
template<class T, class... Args>
auto make_array( Args&&... args )
-> std::array< T, sizeof...(Args) >
{
  return { std::forward<Args>(args)... };
}

但即便如此,也不如人们所愿,因为它不支持像C数组那样的嵌套括号。

假设Foostruct Foo { int x; double y; };。然后使用C样式数组,我们可以:

Foo arr[] = {
  {1,2.2},
  {3,4.5},
};

同时

auto arr = make_array<Foo>(
  {1,2.2},
  {3,4.5}
};

无法编译。您必须为每一行重复Foo

auto arr = make_array<Foo>(
  Foo{1,2.2},
  Foo{3,4.5}
};

是复制粘贴噪声,可能会妨碍代码的表达。

最后,请注意"hello"是一个大小为6的const数组。代码需要知道如何使用C风格的数组。

我对这种情况的典型反应是将C风格的数组和C ++ std::array转换为array_view s,这是一个由两个指针组成的范围,并对它们进行操作。这意味着我不在乎我是否使用基于C或C ++语法的数组:我只关心我输入了一系列数据元素。这些也可以消耗std::dynarraystd::vector s而几乎没有工作。

确实需要撰写array_view,或者从boost窃取一个,或者等待它添加到标准中。

答案 2 :(得分:1)

有时现有的代码库会强制您使用它们

答案 3 :(得分:0)

从技术上讲,您可以根据用途使用std::arraystd::vector重写C风格的数组。

但是,std::array本身使用C风格的数组。 std::array由引擎盖下的C风格数组声明。因此,如果我们想要避免使用编译器魔法,那么这个数组的存在是必不可少的。

template <class T, int N>
class Array
{
    T data[N];
    .
    .

有时写一个小代码,我更喜欢老式数组而不是那些类。 如果您对编译器扩展没有问题,则可以在代码中利用C风格数组的可变长度特性。的(简单)

答案 4 :(得分:0)

我最后一次需要在新代码中使用它们 是我在进行嵌入式工作时,标准库没有实现std::vector或{{ 1}}。在一些较旧的代码库中,由于先前开发人员做出的设计决策,您必须使用数组。

在大多数情况下,如果您使用C ++ 11开始一个新项目,那么旧的C样式数组是一个相当糟糕的选择。这是因为相对于std::array,它们很难得到正确,而这种困难在开发时是直接的花费。这个C ++ FAQ条目总结了我对这个问题的看法:http://www.parashift.com/c++-faq/arrays-are-evil.html

答案 5 :(得分:0)

Pre-C ++ 14:在某些(罕见)情况下,像int这样的类型缺少初始化可以显着提高执行速度。特别是如果某些算法在执行期间需要许多短寿命数组,并且机器没有足够的内存来预分配有意义和/或首先无法知道大小

答案 6 :(得分:0)

C风格的数组在内存受限(并且受到严格限制)的嵌入式系统中非常有用。

阵列允许在没有动态内存分配的情况下进行编程。动态内存分配会生成碎片内存,并且在运行时的某个时刻,内存必须进行碎片整理。在安全关键系统中,在具有关键时序的时段内不会发生碎片整理。

const数组允许将数据放入珍贵的RAM区域中的只读存储器或闪存中。数据可以直接访问,不需要任何额外的初始化时间,如std :: vector或std :: array。

C风格的数组是将原始数据放入程序的便捷工具。例如,图像或字体的位图数据。在没有硬盘驱动器或闪存驱动器的较小嵌入式系统中,必须直接访问数据。 C风格的数组允许这样做。

编辑1:
此外,std :: array不能与不支持C ++ 11或之后的编译器一起使用。

许多公司不希望在项目启动后切换编译器。此外,他们可能需要保留编译器版本以进行维护修复,并且当代理商要求公司重现产品的指定软件版本的问题时。

答案 7 :(得分:0)

我今天发现的原因只有一个:当您想精确地知道数据块的大小并控制它以对齐巨型数据块时。 当您处理流处理器或诸如AVX或SSE的流扩展时,这很有用。 控制数据块分配到内存中一个巨大的单个对齐块很有用。您的对象可以操纵它们负责的分段,完成后,您可以以对齐的方式移动和/或处理巨大的矢量。