std::array
比C数组优越得多。即使我想与旧代码进行交互,我也可以使用std::array::data()
。有没有任何理由我会想要老式数组?
std::array
比C数组优越得多。即使我想与旧代码进行交互,我也可以使用std::array::data()
。有没有任何理由我会想要老式数组?
除非我漏掉了什么(我没有过于密切地关注最近的标准变化),否则大多数C风格数组的用法仍然存在。 std :: array
确实允许静态初始化,但它仍然不会为您计算初始化程序。而且由于在std :: array
之前,C风格数组唯一真正的用途是进行静态初始化的类似表格的操作。
MyStruct const table[] =
{
{ something1, otherthing1 },
// ...
};
使用通常的begin
和end
模板函数(在C++11中采用)来迭代它们。 从初始化器的数量中推断大小,而无需提及大小。
编辑:我忘记的另一件事:字符串字面量仍然是C样式数组;即类型为char[]
。 我不认为任何人会因为我们有了std::array
就排除使用字符串字面量。
const char []
。 - Bulletmagnet不需要。简而言之,用30个字符表示。
当然,实现std::array
需要使用C数组,但这并不是用户想要C数组的理由。此外,std::array
不比C数组性能差,并且还有一种选项可以进行边界检查。最后,任何C++程序都可以依赖于标准库-这就是它成为标准的原因-如果您无法访问标准库,则您的编译器不符合标准,问题标签为"C++",而不是"C++和那些遗漏了一半规范的非C++东西,因为他们觉得不合适"。
std::array
,我会对其产生严重的怀疑。 - Dennis Zickefoose看起来使用 C 数组比使用 std::array
更容易实现多维数组。例如,
char c_arr[5][6][7];
相比之下
std::array<std::array<std::array<char, 7>, 6>, 5> cpp_arr;
此外,由于C数组的自动衰减特性,在上面的示例中c_arr[i]
将衰减为指针,你只需要将其余维度作为另外两个参数传递即可。我的观点是,复制c_arr
并不昂贵。然而,复制cpp_arr[i]
将非常昂贵。
template <typename T, int M, int N> using array2d = std::array<std::array<T, N>, M>;
应该可以解决任何这些问题。 - Miles Routc_arr
复制起来非常耗费资源!你必须自己提供复制代码。它将会衰减为指针,更接近于引用而不是副本,如果你想传递引用,可以使用 std::array
。 - ChetSstd::size_t
而不是int
吧?很抱歉挑剔了一下,但这会使它通用。 - robbiesize_t
。虽然我无法想象有多少情况需要具有超过40亿行或列的数组。 - Miles Rout正如Sumant所说,使用内置的C数组比使用std::array
更容易使用多维数组。
当嵌套时,std::array
可能会变得非常难以阅读且不必要地冗长。
例如:
std::array<std::array<int, 3>, 3> arr1;
相较于
char c_arr[3][3];
此外,请注意,在嵌套 std::array
时, begin()
, end()
和 size()
都会返回无意义的值。 array_2d
和 array_3d
。它们类似于 std::array
,但用于二维和三维的多维数组。它们比内置的多维数组更安全,性能也不差。我没有包含大于3维的多维数组容器,因为这种情况很少见。在C++0x中,可以制作可变参数模板版本,以支持任意数量的维度。//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 }
}};
完整的文档在此处可用:
http://fsma.googlecode.com/files/fsma.html
您可以在此处下载该库:
arr[x][y]
,您无法确定arr
是数组的数组、指针的数组、数组的指针还是指向指针的指针;所有这些实现都是合法的,具体取决于您的需求。而且,多数实际应用场景下需要在运行时确定数组的大小。 - Keith Thompson在C++中可用的C风格数组实际上比真正的C数组要不太灵活。区别在于,在C中,数组类型可以具有运行时大小。以下是有效的C代码,但它既不能用C++ C风格数组表示,也不能用C++ array<>
类型表示:
void foo(int bar) {
double tempArray[bar];
//Do something with the bar elements in tempArray.
}
void foo(int bar) {
double* tempArray = new double[bar];
//Do something with the bar elements behind tempArray.
delete[] tempArray;
}
std::array<>
实现,因为编译时不知道 bar
的大小,需要使用C++的 C 风格数组或std::vector<>
。虽然第一个示例可以相对容易地在C++中表达(尽管需要使用 new[]
和 delete[]
),但是以下内容如果不使用 std::vector<>
就无法在C++中实现。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);
}
问题在于,在C++中,指向行数组 int (*)[width]
的指针不能使用运行时的宽度,这使得任何图像处理代码在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;
}
gcc
)。C11使一些有趣的东西变成可选项,我认为这不是因为他们想禁止该功能。我倾向于把它看作是他们想降低编写符合完全标准的编译器所需的级别的迹象:VLA是非常难以实现的,很多代码可以不用,因此对于某个新平台上的新编译器而言,不必立即实现VLA是有意义的。 - cmaster - reinstate monica也许 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
根据负面评价,我使用的代码在pastebin上(链接)。
基准测试类代码在这里;
我对基准测试不是很了解...我的代码可能有缺陷。
long test_arr_without_init() { return ARR_SIZE; }
。 - R. Martinho Fernandesvoid test_arr_without_init() {}
。你真的需要费尽心思来确保你要测量的代码是你想要测量的代码。 - R. Martinho Fernandesstd::array
的东西std::array
会导致性能下降的原因。 - Xeoat()
中,就像 std::vector
一样,并不在 operator[]
中。对于 std::array
,没有性能降低或代码膨胀的问题,编译器被设计成优化这种情况。当然,添加检查函数是一个优秀的调试工具和重要的优势。@Lou Franco:所有的 C++ 代码都可能依赖于标准库,因为这就是标准库的作用。@Earlz:如果没有 STL 可用,那么就不是 C ++,这就是这个问题的结论。 - Puppystd::array
比等效的C数组用法更大,那么你必须有一个非常糟糕的编译器。 - Puppy
<array>
是一个很重的标准库头文件,可以大大增加编译时间(因标准库实现而异),而C风格的数组不需要任何包含/导入,因为它是核心语言/语法的一部分。 - Matthias