R. *_*des 85 c++ arrays initialization c++11
std::array远远优于C阵列.即使我想与遗留代码进行互操作,我也可以使用std::array::data().有什么理由我想要一个老派阵列吗?
Jam*_*nze 59
除非我错过了一些东西(我没有仔细遵循标准中最近的更改),C样式数组的大部分用法仍然存在. std::array允许静态初始化,但它仍然不会为您计算初始值设定项.并且因为之前C样式数组的唯一真正用途std::array是静态初始化表格,如下所示:
MyStruct const table[] =
{
{ something1, otherthing1 },
// ...
};
Run Code Online (Sandbox Code Playgroud)
使用常用begin和end模板函数(在C++ 11中采用)来迭代它们.没有提到编译器根据初始化器的数量确定的大小.
编辑:我忘了另一件事:字符串文字仍然是C样式数组; 即与类型char[].我不认为任何人会因为我们的原因而排除使用字符串文字std::array.
Pup*_*ppy 29
不,呃,直截了当地说.并且有30个字符.
当然,您需要实现C数组std::array,但这并不是用户想要C数组的真正原因.此外,不,std::array性能不比C数组低,并且具有边界检查访问的选项.最后,任何C++程序都依赖于标准库是完全合理的 - 这就是它的标准 - 如果你没有访问标准库,那么你的编译器是不符合标准的问题被标记为"C++",而不是"C++和那些非C++的东西错过了一半的规范,因为他们感觉不合适."
Sum*_*ant 25
使用C维数组比使用多维数组更容易std::array.例如,
char c_arr[5][6][7];
Run Code Online (Sandbox Code Playgroud)
而不是
std::array<std::array<std::array<char, 7>, 6>, 5> cpp_arr;
Run Code Online (Sandbox Code Playgroud)
此外,由于C数组的自动衰减属性,c_arr[i]在上面的示例中将衰减为指针,您只需将剩余的维度作为另外两个参数传递.我的观点是c_arr复制并不昂贵.但是,cpp_arr[i]复制起来会非常昂贵.
Ric*_*y65 13
正如Sumant所说,使用内置C阵列比使用多维数组要容易得多std::array.
嵌套时,std::array可能会变得非常难以阅读并且不必要地冗长.
例如:
std::array<std::array<int, 3>, 3> arr1;
Run Code Online (Sandbox Code Playgroud)
相比
char c_arr[3][3];
Run Code Online (Sandbox Code Playgroud)
另外,还要注意begin(),end()并size()全部返回无意义的值,当你窝std::array.
出于这些原因,我已经创建了自己的固定大小的多维数组容器,array_2d并且array_3d.它们类似于std::array2维和3维的多维数组.它们比内置的多维数组更安全,性能更差.我没有包含尺寸大于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 }
}};
Run Code Online (Sandbox Code Playgroud)
完整文档可在此处获得:
http://fsma.googlecode.com/files/fsma.html
你可以在这里下载这个库:
http://fsma.googlecode.com/files/fsma.zip
C++中提供的C风格数组实际上比真正的C数组更不通用.不同之处在于,在C中,数组类型可以具有运行时大小.以下是有效的C代码,但既不能用C++ C风格的数组表示,也不能用C++ array<>类型表示:
void foo(int bar) {
double tempArray[bar];
//Do something with the bar elements in tempArray.
}
Run Code Online (Sandbox Code Playgroud)
在C++中,您必须在堆上分配临时数组:
void foo(int bar) {
double* tempArray = new double[bar];
//Do something with the bar elements behind tempArray.
delete[] tempArray;
}
Run Code Online (Sandbox Code Playgroud)
这是无法实现的std::array<>,因为bar在编译时不知道,它需要在C++中使用C风格的数组或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);
}
Run Code Online (Sandbox Code Playgroud)
关键是,指向行数组的指针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;
}
Run Code Online (Sandbox Code Playgroud)
此代码与上面的C代码完全相同,但它需要在使用索引的任何地方手动执行索引计算.对于2D情况,这仍然是可行的(即使它有很多机会使索引计算错误).不过,它在3D情况下变得非常讨厌.
我喜欢用C++编写代码.但每当我需要操作多维数据时,我真的会问自己是否应该将代码的这一部分移到C.