"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])时,它与初始化程序一起工作得很好。那是因为数组的大小在编译时

是已知的

rowscolumns 初始化为 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
}

即使您将 rowscolumns 设为常量 - 如 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 可能是一种更优雅的方式。