在C ++中,您可以轻松地分配一维数组:
T *array=new T[N];
你也可以用一个语句删除它:
delete[] array;
编译器将知道如何解除分配正确的字节数的魔力。
但为什么不能像这样分配二维数组?
T *array=new T[N,M];
或者甚至喜欢这个?
T *array=new T[N,M,L];
如果你想要一个多维,你必须这样做:
T **array=new T*[N];
for(int i=0;i<N;i++) array[i]=new T[M];
如果你想要一个使用矩阵的快速程序(矩阵运算,特征值算法等等),你可能也希望利用缓存来获得最佳性能,这需要数据在同一个地方。使用vector<vector<T> >
是相同的情况。在C中,您可以在堆栈上使用可变长度数组,但是您无法在堆上分配它们(并且堆栈空间非常有限),您也可以在C ++中执行可变长度数组,但它们不会出现在C中++ 0x中。
唯一的解决方法是相当hackish和错误 -
T *array=new T[N*M];
for(int i=0;i<N;i++)
for(int j=0;j<M;j++)
{
T[i*N+j]=...;
}
答案 0 :(得分:8)
执行T *array=new T[N*M];
的方法是最接近真正的多维数组。请注意,要找到此数组中的元素,您需要M
的值(我相信您的示例是错误的,它应该是T[i*M+j]
),这只在运行时才知道。
在编译时分配2D数组时,比如array[5][10]
,值10
是一个常量,因此编译器只需生成用于计算i*10+j
的代码。但是,如果您执行new T[N,M]
,则表达式i*M+j
取决于分配数组时M
的值。编译器需要一些方法来存储M
的值以及实际的数组本身,事情只会从这里变得混乱。我想这就是为什么他们决定不在语言中包含这样的功能。
至于你的解决方法,你可以通过编写一个重载operator ()
的包装类来减少“hackish”,这样你就可以做array(i, j) = ...
之类的事情。
答案 1 :(得分:3)
因为多维数组与数组/指针数组不同。
答案 2 :(得分:1)
使用std :: vector
答案 3 :(得分:1)
为什么不能在C ++中使用一个新调用分配多维数组?
因为当ISO编写C ++语言标准时,他们并没有决定将该功能添加到该语言中。我不知道为什么他们决定不这样做。
如果您不喜欢,可以创建辅助函数来分配/释放多维数组,或者可以切换到支持轻松分配多维数组的C#或Java等语言。
答案 4 :(得分:0)
然而,您可以做的是从堆中分配包含二维数组的对象。我只想为它编写一个包装类。
答案 5 :(得分:0)
昨晚我正在考虑这个问题,这个解决方案来找我。
T * raw = new T[N*M];
T ** array = new T*[N];
for(int i=0; i<N; i++)
array[i] = raw + i * M;
现在“数组”的行为就像一个连续的静态大小的二维数组。您只需要删除原始数组和多维数组。
答案 6 :(得分:0)
我建议您使用同名库中的Boost::multi_array,它提供了一个多维数组的简单接口。它可以在一行中分配,并且在足够高的优化级别通常与本机阵列一样快。
以下是图书馆网站的一些示例代码:
#include "boost/multi_array.hpp"
#include <cassert>
int
main () {
// Create a 3D array that is 3 x 4 x 2
typedef boost::multi_array<double, 3> array_type;
typedef array_type::index index;
array_type A(boost::extents[3][4][2]);
// Assign values to the elements
int values = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
A[i][j][k] = values++;
// Verify values
int verify = 0;
for(index i = 0; i != 3; ++i)
for(index j = 0; j != 4; ++j)
for(index k = 0; k != 2; ++k)
assert(A[i][j][k] == verify++);
return 0;
}
答案 7 :(得分:-1)
因为逗号是操作符。
int a = (3, 5, 7, 9);
程序将评估3,丢弃结果, 评价5,丢弃结果, 评估7,丢弃结果, 评估9,并将其分配给。
因此,您正在寻找的语法无法使用, 并保留向后兼容c。