"Variable may not be initialized" 用另一个变量指定数组大小时
"Variable may not be initialized" when specifying the array size with another variable
我正在尝试编译以下代码:
int rows = 4;
int columns = 4;
int numblock[columns][rows] = {
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}
};
它告诉我变量可能没有被初始化。当我改写 int numblock[4][4] 时,编译器不会抱怨。
我猜和这个有关:C compile error: "Variable-sized object may not be initialized"
谁能给我解释一下吗?
编辑 - 来自 op 的评论:
..我设置列和行= 4。它应该知道大小,不是吗?
答案已经在您提供的 link 中,但我会尽力澄清,因为 linked 的答案对您来说不是很清楚。
首先 - 您所拥有的称为 VLA,即可变长度数组。这个想法很简单,您可以使用另一个变量来设置数组的大小。所以这允许在 运行 时间 .
设置大小
您遇到的问题是因为:不允许初始化 VLA
就这么简单 - 它在 C 中不受支持。
当数组是用数字定义的(例如[4][4]
)时,它与初始化程序一起工作得很好。那是因为数组的大小在编译时
是已知的
将 rows
和 columns
初始化为 4 的事实没有区别。编译器不跟踪这些变量在创建数组之前是否被更改。比如像这样:
void foo()
{
int rows = 4;
int columns = 4;
rows = rows + 42; // or scanf("%d", &rows) to get the number of rows from a user
int numblock[columns][rows]; // no - initializer here - not allowed
}
即使您将 rows
和 columns
设为常量 - 如 const int rows = 4;
- 它在 C 中仍然不起作用(但在 C++ 中它会)。
"initialize" VLA 的一种方法是使用 memset - 例如:
void foo()
{
int rows = 4;
int columns = 4;
int numblock[columns][rows]; // no - initializer here - not allowed
memset(numblock, 0, sizeof numblock); // but using memset is easy
}
如果你想要固定数量的rows/columns,C 方法是使用defines
。喜欢:
#define ROWS 4
#define COLUMNS 4
void foo()
{
int numblock[ROWS][COLUMNS] = {
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}
};
}
这会起作用,因为 defines
在 编译时解析
我发现如果我在变量声明中将 n 初始化为 0,但直到程序主体内部 (int main ()) 才初始化数组,编译器不会报错并且程序运行正如预期的那样。这可能不是首选方式,我认为使用#define 可能是一种更优雅的方式。
我正在尝试编译以下代码:
int rows = 4;
int columns = 4;
int numblock[columns][rows] = {
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}
};
它告诉我变量可能没有被初始化。当我改写 int numblock[4][4] 时,编译器不会抱怨。
我猜和这个有关:C compile error: "Variable-sized object may not be initialized"
谁能给我解释一下吗?
编辑 - 来自 op 的评论:
..我设置列和行= 4。它应该知道大小,不是吗?
答案已经在您提供的 link 中,但我会尽力澄清,因为 linked 的答案对您来说不是很清楚。
首先 - 您所拥有的称为 VLA,即可变长度数组。这个想法很简单,您可以使用另一个变量来设置数组的大小。所以这允许在 运行 时间 .
设置大小您遇到的问题是因为:不允许初始化 VLA
就这么简单 - 它在 C 中不受支持。
当数组是用数字定义的(例如[4][4]
)时,它与初始化程序一起工作得很好。那是因为数组的大小在编译时
将 rows
和 columns
初始化为 4 的事实没有区别。编译器不跟踪这些变量在创建数组之前是否被更改。比如像这样:
void foo()
{
int rows = 4;
int columns = 4;
rows = rows + 42; // or scanf("%d", &rows) to get the number of rows from a user
int numblock[columns][rows]; // no - initializer here - not allowed
}
即使您将 rows
和 columns
设为常量 - 如 const int rows = 4;
- 它在 C 中仍然不起作用(但在 C++ 中它会)。
"initialize" VLA 的一种方法是使用 memset - 例如:
void foo()
{
int rows = 4;
int columns = 4;
int numblock[columns][rows]; // no - initializer here - not allowed
memset(numblock, 0, sizeof numblock); // but using memset is easy
}
如果你想要固定数量的rows/columns,C 方法是使用defines
。喜欢:
#define ROWS 4
#define COLUMNS 4
void foo()
{
int numblock[ROWS][COLUMNS] = {
{0,0,0,0},
{0,0,0,0},
{0,0,0,0},
{0,0,0,0}
};
}
这会起作用,因为 defines
在 编译时解析
我发现如果我在变量声明中将 n 初始化为 0,但直到程序主体内部 (int main ()) 才初始化数组,编译器不会报错并且程序运行正如预期的那样。这可能不是首选方式,我认为使用#define 可能是一种更优雅的方式。