«Переменная не может быть инициализирована» при указании размера массива с другой переменной - PullRequest
0 голосов
/ 30 марта 2019

Я пытаюсь скомпилировать следующий код:

    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: «Объект переменного размера не может быть инициализирован»

Может кто-нибудь объяснить мне это?

Редактировать - из комментария по оп:

.. Я установил столбцы и строки = 4. Он должен знать размер, не так ли?

Ответы [ 2 ]

1 голос
/ 30 марта 2019

Ответ уже находится в указанной вами ссылке, но я постараюсь уточнить, поскольку связанный ответ вам не ясен.

Первое - то, что у вас есть, называется 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 ++ это будет).

Одним из способов "инициализации" 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
}

Если вы хотите фиксированное количество строк / столбцов, 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 разрешены в время компиляции

0 голосов
/ 30 марта 2019

Я обнаружил, что если я инициализирую n в 0 в объявлениях переменных, но не инициализирую массив до тех пор, пока внутри тела программы (int main ()), компилятор не будет жаловаться, и программа будет функционировать, как ожидается,Это не может быть предпочтительным способом, и я думаю, что использование #define может быть более элегантным способом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...