声明二维数组时
int random[height][width];
然后在函数中使用它
void populate(int random[height][width], int x, int y)
给出在任何函数之外声明的错误可变大小类型. 我知道我做错了什么,而且这是一件小事。我只是记性不好...
声明二维数组时
int random[height][width];
然后在函数中使用它
void populate(int random[height][width], int x, int y)
给出在任何函数之外声明的错误可变大小类型. 我知道我做错了什么,而且这是一件小事。我只是记性不好...
我现在要站出来告诉你,多维数组不值得在 C 或 C++ 中花费脑力。最好使用一维数组(或者更好的是标准容器)并编写索引函数:
inline int index (int x, int y)
{
return x + y * width;
}
现在解决你的问题。C++ 不支持 C99 可变长度数组。编译器必须在编译时知道数组的大小。例如,以下内容将不起作用。
int dim = 4;
int ar[dim];
如果dim
是const
,它会起作用,因为编译器将能够准确判断ar
应该有多宽(因为 的值dim
不会改变)。这可能是您遇到的问题。
如果您希望能够在编译时更改大小,则需要做一些更困难的事情,例如编写模板化参考。您不能将指针用于多维数组,因为它们在 C/C++ 中的布局方式。一个模板化的例子可能看起来像下面的异常:
template <int Width, int Height>
void populate(int (&(&random)[Width])[Height], int x, int y);
这很丑陋。
对于运行时,您需要使用new
来分配数据,或者使用容器类型。
我将用一个例子来说明:
//全局变量
const int ARRAY_SIZE = 16
struct ArrayType_t arrayType[ARRAY_SIZE];
即使 ARRAY_SIZE 被声明为常量 int,它的值也不会在编译时初始化,因此编译器不知道数组的大小并给出这样的错误。但是,如果您将其设置为哈希定义
#define ARRAY_SIZE 16
struct ArrayType_t arrayType[ARRAY_SIZE]
===>,则此方法有效,因为 ARRAY_SIZE 是在编译时定义的,并且编译器可以在编译时知道数组的大小。
您不能在函数之外定义具有非常量维度(宽度、高度)的数组,也就是说 - 不在堆栈框架中,因为在编译时维度是未知的。您将使用常量或动态分配它(在堆中或堆栈帧中)。
当数组直接作为参数传递给函数(按值传递)时,它会衰减为指向数组第一个元素的指针。即使您可以在签名中清楚地读取数组的维度,编译器也会忽略这些维度。该行为与 C 兼容。
使用 C++,您可以通过引用传递数组,这将不再是问题。
int extract_value( int (&a)[10][10], int row, int col ) {
return a[row][col];
}
int main() {
int a[10][10] = {};
a[5][5] = 1;
std::cout << extract_value( a, 5, 5 ) << std::endl;
int b[5][5];
// extract_value( b, 2, 2 ); // error: the function takes an array of 10x10
}
函数参数必须完全匹配,即它只需要一个 10x10 元素的数组。您可以通过在数组大小上模板化函数来摆脱该限制。一旦你在它也类型:
template <typename T, int Rows, int Cols>
T extract_value( T (&a)[Rows][Cols], int row, int col ) {
return a[row][col];
}
int main() {
int a[5][7] = {};
extract_value( a, 3, 4 );
int b[8][2] = {};
extract_value( b, 7, 1 ); // correct, the compiler matches sizes
double c[4][4] = {};
extract_value( c, 2, 2 ); // different types are allowed
}
这个解决方案仍然很麻烦,因为大小必须是编译时常量,并且数组必须是堆栈分配的。对此的解决方案是定义一些类,该类在缓冲区(线性)中获取动态内存,并从 N 坐标系转换为一维数组以获得值,如前所述。您可以在这个关于提供二维矩阵实现的运算符重载的常见问题解答中获得有关如何执行此操作的一些提示。一旦你实现了它,你就可以将它用作函数/方法的参数。
我的建议是遵循最后一条路径:将 N 维数组封装到一个类中,该类提供到一维向量的转换(C++FAQ lite 使用原始指针,我更喜欢 STL 容器)。
你可以使用这样的东西:
void populate(int height, int width, int **random)
{
//here you can work from random[0][0] to random[height][width]
}
那么你可以像这样使用它:
int main()
{
int height=10;
int width=20;
int **myarray = new int*[height];
for( int i=0; i< height; i++ ) myarray[i] = new int[width];
populate( height, width, myarray);
}
但是,当然,您必须注意缓冲区溢出