既然我们有了 std::array,C 风格的数组还有什么用处?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6111565/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 19:30:47  来源:igfitidea点击:

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

c++arraysc++11initialization

提问by R. Martinho Fernandes

std::arrayis vastly superior to the C arrays. And even if I want to interoperate with legacy code, I can just use std::array::data(). Is there any reason I would ever want an old-school array?

std::array远远优于C数组。即使我想与遗留代码互操作,我也可以只使用std::array::data(). 我有什么理由想要一个老式的阵列吗?

采纳答案by James Kanze

Unless I've missed something (I've not followed the most recent changes in the standard too closely), most of the uses of C style arrays still remain. std::arraydoes allow static initialization, but it still won't count the initializers for you. And since the only real use of C style arrays before std::arraywas for statically initialized tables along the lines of:

除非我遗漏了一些东西(我没有太密切地关注标准中的最新变化),C 风格数组的大部分用途仍然存在。 std::array确实允许静态初始化,但它仍然不会为您计算初​​始化器。并且因为之前 C 风格数组的唯一真正用途std::array是用于静态初始化的表:

MyStruct const table[] =
{
    { something1, otherthing1 },
    //  ...
};

using the usual beginand endtemplate functions (adopted in C++11) to iterate over them. Without ever mentionning the size, which the compiler determines from the number of initializers.

使用常用函数beginend模板函数(在 C++11 中采用)来迭代它们。从来没有提到编译器根据初始化程序的数量确定的大小。

EDIT: Another thing I forgot: string literals are still C style arrays; i.e. with type char[]. I don't think that anyone would exclude using string literals just because we have std::array.

编辑:我忘记的另一件事:字符串文字仍然是 C 风格的数组;即与类型char[]。我认为没有人会因为我们有std::array.

回答by Puppy

No. To, uh, put it bluntly. And in 30 characters.

不,呃,坦率地说。并且在 30 个字符中。

Of course, you need C arrays to implement std::array, but that's not really a reason that a user would ever want C arrays. In addition, no, std::arrayis not less performant than a C array, andhas an option for a bounds-checked access. And finally, it is completely reasonable for any C++ program to depend on the Standard library- that's kind of the point of it being Standard- and if you don't have access to a Standard library, then your compiler is non-conformant and the question is tagged "C++", not "C++ and those not-C++ things that miss out half the specification because they felt it inappropriate.".

当然,您需要 C 数组来实现std::array,但这并不是用户想要 C 数组的真正原因。此外,不,std::array它的性能不低于 C 数组,并且具有边界检查访问的选项。最后,任何 C++ 程序依赖于标准库是完全合理的——这就是它成为标准的一点——如果你无权访问标准库,那么你的编译器就是不符合标准的,并且问题被标记为“C++”,而不是“C++ 和那些因为觉得不合适而错过一半规范的非 C++ 东西。”。

回答by Sumant

Seems like using multi-dimensional arrays is easier with C arrays than std::array. For instance,

似乎使用 C 数组比使用多维数组更容易std::array。例如,

char c_arr[5][6][7];

as opposed to

std::array<std::array<std::array<char, 7>, 6>, 5> cpp_arr;

Also due to the automatic decay property of C arrays, c_arr[i]in the above example will decay to a pointer and you just need to pass the remaining dimensions as two more parameters. My point is it c_arris not expensive to copy. However, cpp_arr[i]will be very costly to copy.

同样由于 C 数组的自动衰减属性,c_arr[i]在上面的示例中将衰减为一个指针,您只需要将剩余的维度作为另外两个参数传递。我的观点是c_arr复制并不昂贵。但是,cpp_arr[i]复制将非常昂贵。

回答by Ricky65

As Sumant said, multi-dimensional arrays are a lot easier to use with built in C-arrays than with std::array.

正如苏曼特所说,与内置 C 数组相比,多维数组更容易使用std::array

When nested, std::arraycan become very hard to read and unnecessarily verbose.

嵌套时,std::array可能会变得非常难以阅读和不必要的冗长。

For example:

例如:

std::array<std::array<int, 3>, 3> arr1; 

compared to

相比

char c_arr[3][3]; 

Also, note that begin(), end()and size()all return meaningless values when you nest std::array.

另外,请注意begin(),end()size()嵌套时都返回无意义的值std::array

For these reasons I've created my own fixed size multidimensional array containers, array_2dand array_3d. They are analogous to std::arraybut for multidimensional arrays of 2 and 3 dimensions. They are safer and have no worse performance than built-in multidimensional arrays. I didn't include a container for multidimensional arrays with dimensions greater than 3 as they are uncommon. In C++0x a variadic template version could be made which supports an arbitrary number of dimensions.

由于这些原因,我创建了自己的固定大小的多维数组容器,array_2d并且array_3d. 它们类似于std::array2 维和 3 维多维数组。它们更安全,性能也不比内置多维数组差。我没有包含维度大于 3 的多维数组的容器,因为它们不常见。在 C++0x 中,可以制作支持任意维数的可变参数模板版本。

An example of the two-dimensional variant:

二维变体的一个例子:

//Create an array 3 x 5 (Notice the extra pair of braces) 

fsma::array_2d <double, 3, 5> my2darr = {{
    { 32.19, 47.29, 31.99, 19.11, 11.19},
    { 11.29, 22.49, 33.47, 17.29, 5.01 },
    { 41.97, 22.09, 9.76, 22.55, 6.22 }
}};

Full documentation is available here:

完整文档可在此处获得:

http://fsma.googlecode.com/files/fsma.html

http://fsma.googlecode.com/files/fsma.html

You can download the library here:

您可以在此处下载库:

http://fsma.googlecode.com/files/fsma.zip

http://fsma.googlecode.com/files/fsma.zip

回答by cmaster - reinstate monica

The C-style arrays that are available in C++ are actually much less versatile than the real C-arrays. The difference is, that in C, array types can have runtimesizes. The following is valid C code, but it can neither be expressed with C++ C-style arrays nor with the C++ array<>types:

C++ 中可用的 C 样式数组实际上比真正的 C 数组通用得多。不同之处在于,在 C 中,数组类型可以具有运行时大小。以下是有效的 C 代码,但它既不能用 C++ C 样式数组表示,也不能用 C++array<>类型表示:

void foo(int bar) {
    double tempArray[bar];
    //Do something with the bar elements in tempArray.
}

In C++, you would have to allocate the temporary array on the heap:

在 C++ 中,您必须在堆上分配临时数组:

void foo(int bar) {
    double* tempArray = new double[bar];
    //Do something with the bar elements behind tempArray.
    delete[] tempArray;
}

This cannot be achieved with std::array<>, because baris not known at compile time, it requires the use of either C-style arrays in C++ or of std::vector<>.

这无法通过 实现std::array<>,因为bar在编译时未知,它需要在 C++ 或 中使用 C 样式数组std::vector<>



While the first example could relatively easily be expressed in C++ (albeit requiring new[]and delete[]), the following cannot be achieved in C++ without std::vector<>:

虽然第一个示例可以相对容易地用 C++ 表达(尽管需要new[]delete[]),但如果没有 ,则无法在 C++ 中实现以下内容std::vector<>

void smoothImage(int width, int height, int (*pixels)[width]) {
    int (*copy)[width] = malloc(height*sizeof(*copy));
    memcpy(copy, pixels, height*sizeof(*copy));
    for(y = height; y--; ) {
        for(x = width; x--; ) {
            pixels[y][x] = //compute smoothed value based on data around copy[y][x]
        }
    }
    free(copy);
}

The point is, that the pointers to the line arrays int (*)[width]cannot use a runtime width in C++, which makes any image manipulation code much more complicated in C++ than it is in C. A typical C++ implementation of the image manipulation example would look like this:

关键是,指向线数组的指针int (*)[width]不能在 C++ 中使用运行时宽度,这使得 C++ 中的任何图像处理代码比 C 中的要复杂得多。图像处理示例的典型 C++ 实现如下所示:

void smoothImage(int width, int height, int* pixels) {
    int* copy = new int[height*width];
    memcpy(copy, pixels, height*width*sizeof(*copy));
    for(y = height; y--; ) {
        for(x = width; x--; ) {
            pixels[y*width + x] = //compute smoothed value based on data around copy[y*width + x]
        }
    }
    delete[] copy;
}

This code does precisely the same calculations as the C code above, but it needs to perform the index computation by hand wherever the indices are used. For the 2D case, this is still feasible (even though it comes with a lot of opportunities to get the index calculation wrong). It gets really nasty in the 3D case, though.

此代码与上面的 C 代码执行完全相同的计算,但它需要在使用索引的任何地方手动执行索引计算。对于 2D 情况,这仍然是可行的(即使它有很多机会使索引计算出错)。但是,在 3D 情况下它变得非常讨厌。

I like writing code in C++. But whenever I need to manipulate multidimensional data, I really ask myself whether I should move that part of the code to C.

我喜欢用 C++ 编写代码。但是每当我需要操作多维数据时,我都会问自己是否应该将那部分代码移到 C 中。

回答by K'Prime

May be the std::arrayis not slow. But I did some benchmarking using simple store and read from the std::array; See the below benchmark results (on W8.1, VS2013 Update 4):

可能std::array是不慢。但是我使用简单的存储做了一些基准测试并从 std::array 中读取;请参阅以下基准测试结果(在 W8.1、VS2013 Update 4 上):

ARR_SIZE: 100 * 1000
Avrg = Tick / ARR_SIZE;

test_arr_without_init
==>VMem: 5.15Mb
==>PMem: 8.94Mb
==>Tick: 3132
==>Avrg: 0.03132
test_arr_with_init_array_at
==>VMem: 5.16Mb
==>PMem: 8.98Mb
==>Tick: 925
==>Avrg: 0.00925
test_arr_with_array_at
==>VMem: 5.16Mb
==>PMem: 8.97Mb
==>Tick: 769
==>Avrg: 0.00769
test_c_arr_without_init
==>VMem: 5.16Mb
==>PMem: 8.94Mb
==>Tick: 358
==>Avrg: 0.00358
test_c_arr_with_init
==>VMem: 5.16Mb
==>PMem: 8.94Mb
==>Tick: 305
==>Avrg: 0.00305

According to the negative marks, the code I used is in the pastebin (link)

根据负分,我使用的代码在pastebin(链接)中

The benchmark class code is here;

基准类代码在这里

I don't know a lot about benchmarkings... My code may be flawed

我对基准测试不太了解……我的代码可能有缺陷

回答by Lou Franco

  1. to implement something like std::array
  2. if you don't want to use the STL or can't
  3. For performance
  1. 实现类似的东西 std::array
  2. 如果您不想使用 STL 或不能
  3. 为了性能