现在我们有std :: array什么用于C风格的数组?
std::array
远远优于C数组。 即使我想与遗留代码进行互操作,我也可以使用std::array::data()
。 有没有什么原因我会想要一个老式的arrays?
除非我错过了一些东西(我没有太紧密地跟随标准中的最新变化),大多数C风格的数组的使用依然存在。 std::array
允许静态初始化,但是它仍然不会为你计算初始值。 而且由于在std::array
之前唯一真正使用C风格的std::array
是用于静态初始化的表,如下所示:
MyStruct const table[] = { { something1, otherthing1 }, // ... };
使用通常的begin
和end
模板函数(在C ++ 11中采用)遍历它们。 没有提到编译器根据初始化程序的数量确定的大小。
编辑:另一件我忘记了:string文字仍然是C风格的数组; 即与typeschar[]
。 我不认为有人会因为我们有std::array
而排除使用string文字。
不,不客气地说。 并在30个字符。
当然,你需要C数组来实现std::array
,但这不是用户想要C数组的原因。 另外,不, std::array
性能不如C数组低, 并且有一个边界检查访问的选项。 最后,任何C ++程序都依赖于标准库是完全合理的 – 这就是标准库的一个要点 – 如果你不能访问标准库,那么你的编译器是不符合标准的问题被标记为“C ++”,而不是“C ++”以及那些因为感觉不合适而错过了一半规范的非C ++事物。
似乎使用multidimensional array比使用std::array
更容易。 例如,
char c_arr[5][6][7];
而不是
std::array<std::array<std::array<char, 7>, 6>, 5> cpp_arr;
另外,由于C数组的自动衰减属性,上例中的c_arr[i]
将衰减为一个指针,并且只需要将剩余的维数作为另外两个parameter passing。 我的观点是,复制c_arr
并不昂贵。 但是, cpp_arr[i]
复制的代价非常高。
正如Sumant所说,与使用std::array
相比,multidimensional array更容易使用内build的C std::array
。
当嵌套时, std::array
可能变得非常难以阅读并且不必要地冗长。
例如:
std::array<std::array<int, 3>, 3> arr1;
相比
char c_arr[3][3];
另外请注意,当您嵌套std::array
时, begin()
, end()
和size()
都会返回无意义的值。
由于这些原因,我创build了自己的固定大小的multidimensional array容器array_2d
和array_3d
。 它们类似于std::array
但对于2维和3维的multidimensional array。 它们比内置的多维arrays更安全,性能更差。 我没有包含一个尺寸大于3的multidimensional array的容器,因为它们不常见。 在C ++ 0x中,可以创build一个支持任意数量维度的可变模板版本。
二维变体的一个例子:
//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 } }};
完整的文档可在这里find:
http://fsma.googlecode.com/files/fsma.html
你可以在这里下载图书馆:
在C ++中可用的C风格的数组实际上比真正的C数组要less得多。 不同的是,在C中,数组types可以具有运行时大小。 以下是有效的C代码,但它既不能用C ++ C风格的数组也不能用C ++ array<>
types表示:
void foo(int bar) { double tempArray[bar]; //Do something with the bar elements in tempArray. }
在C ++中,你将不得不在堆上分配临时数组:
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[]
)相对容易地expression,但是如果没有std::vector<>
,C ++将无法实现以下function:
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); }
重点是,指向行数组int (*)[width]
的指针不能在C ++中使用运行时宽度,这使得任何image processing代码在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; }
这段代码的计算和上面的C代码完全一样,但是无论使用索引 ,它都需要手动执行索引计算。 对于二维情况来说,这仍然是可行的(尽pipe它有很多机会让索引计算错误)。 不过,它在3D情况下变得非常讨厌。
我喜欢用C ++编写代码。 但是,无论何时我需要操作多维数据,我都会问自己是否应该将这部分代码移到C
可能是std::array
不慢。 但是我使用简单的存储做了一些基准testing,并从std :: array中读取; 请参阅以下基准testing结果(在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( 链接 )
基准类代码在这里 ;
我不太了解基准testing…我的代码可能有缺陷
- 实现类似
std::array
东西 - 如果你不想使用STL或不能
- 为了performance