声明二维数组时
int random[height][width];
然后在函数中使用它
void populate(int random[height][width], int x, int y)
给出在任何函数之外声明的错误变量大小类型。 我知道我做错了什么,而且它的东西很小。我的记忆力很差......
答案 0 :(得分:4)
我现在要站出来告诉你多维数组在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
来分配数据,或使用容器类型。
答案 1 :(得分:1)
您无法在函数外部定义具有非常量维度(宽度,高度)的数组,即 - 不在堆栈框架中,因为在编译时不知道尺寸。您可以使用常量或动态分配它(在堆中或堆栈帧中)。
答案 2 :(得分:1)
当一个数组作为参数直接传递给一个函数(按值传递)时,它会衰减成一个指向数组第一个元素的指针。即使您可以在签名中清楚地读取数组的维度,编译器也会忽略这些维度。该行为与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坐标系到1维数组的转换以获得值,如之前所建议的那样。您可以在此FAQ中获取有关如何执行此操作的一些提示,该操作符重载提供了2D矩阵的实现。实现后,您可以将其用作函数/方法的参数。
我的建议是遵循最后一条路径:将N维数组封装到一个提供转换为1D向量的类中(C ++ FAQ lite使用原始指针,我更喜欢STL容器)。
答案 3 :(得分:1)
我将用例如:
来说明//全局
const int ARRAY_SIZE = 16
struct ArrayType_t arrayType[ARRAY_SIZE];
即使ARRAY_SIZE被声明为常量int,它的值也不会在编译时初始化,因此编译器不知道数组的大小并且给出了这样的错误。但是,如果您将其作为哈希定义
#define ARRAY_SIZE 16
struct ArrayType_t arrayType[ARRAY_SIZE]
===&gt;这是有效的,因为定义了ARRAY_SIZE
编译时,编译器可以在编译时知道数组的大小。
答案 4 :(得分:-1)
您可以使用以下内容:
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);
}
但是,当然,你必须注意缓冲区溢出