在TR1和C ++ 11中的std::vector
和std::array
之间,对于动态和固定大小的数组都有安全的替代方案,这些数组知道自己的长度并且不会出现可怕的指针/数组二元性。
所以我的问题是,当C阵列必须必须时,C ++中是否存在任何情况(除了调用C库代码之外),或者"禁止"他们一共?
修改
感谢所有人的回复,但事实证明这个问题是
的重复Now that we have std::array what uses are left for C-style arrays?
所以我会引导所有人去看那里。
[我不确定如何关闭我自己的问题,但如果主持人(或更多有投票的人)徘徊过去,请随意将其标记为复制并删除此句子。] < / p>
答案 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数组那样的嵌套括号。
假设Foo
为struct 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::dynarray
和std::vector
s而几乎没有工作。
确实需要撰写array_view
,或者从boost
窃取一个,或者等待它添加到标准中。
答案 2 :(得分:1)
有时现有的代码库会强制您使用它们
答案 3 :(得分:0)
从技术上讲,您可以根据用途使用std::array
或std::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的流扩展时,这很有用。 控制数据块分配到内存中一个巨大的单个对齐块很有用。您的对象可以操纵它们负责的分段,完成后,您可以以对齐的方式移动和/或处理巨大的矢量。