Подтвердить что ты не робот

С++ array - выражение должно иметь постоянное значение

Я получаю сообщение об ошибке, когда пытаюсь создать массив из объявленных переменных.

int row = 8;
int col= 8;
int [row][col];

Почему я получаю эту ошибку:

выражение должно иметь постоянное значение.

4b9b3361

Ответ 1

При создании такого массива его размер должен быть постоянным. Если вам нужен массив с динамическим размером, вам нужно выделить память для него в куче, и вам также нужно будет освободить его с помощью delete, когда вы закончите:

//allocate the array
int** arr = new int*[row];
for(int i = 0; i < row; i++)
    arr[i] = new int[col];

// use the array

//deallocate the array
for(int i = 0; i < row; i++)
    delete[] arr[i];
delete[] arr;

Если вы хотите фиксированный размер, тогда они должны быть объявлены как const:

const int row = 8;
const int col = 8;
int arr[row][col];

Кроме того,

int [row][col];

даже не предоставляет имя переменной.

Ответ 2

С++ не позволяет использовать непостоянные значения для размера массива. Это так, как оно было разработано.

C99 позволяет размеру массива быть переменной, но я не уверен, что это разрешено для двух измерений. Некоторые компиляторы С++ (gcc) разрешают это как расширение, но вам может потребоваться включить параметр компилятора, чтобы разрешить его.

И я почти пропустил это - вам нужно объявить имя переменной, а не только размеры массива.

Ответ 3

Стандарт требует, чтобы длина массива была значением, которое можно вычислить во время компиляции, чтобы компилятор мог выделить достаточно места в стеке. В вашем случае вы пытаетесь установить длину массива на значение, которое неизвестно во время компиляции. Да, я знаю, что кажется очевидным, что он должен быть известен компилятору, но здесь это не так. Компилятор не может делать никаких предположений о содержимом непостоянных переменных. Итак, идите с:

const int row = 8;
const int col= 8;
int a[row][col];

UPD: некоторые компиляторы фактически позволят вам снять это. IIRC, g++ имеет эту функцию. Однако никогда не используйте его, потому что ваш код станет не переносимым для компиляторов.

Ответ 4

Вы можете использовать #define в качестве альтернативного решения, которое не вводит вектор и malloc, и вы все еще используете один и тот же синтаксис при определении массива.

#define row 8
#define col 8

in main()
{
int [row][col];
}

Ответ 5

Когда вы объявляете переменную как здесь

int a[10][10];

вы сообщаете компилятору С++, что во время выполнения вы хотите, чтобы 100 последовательных целых чисел были выделены в программную память. Затем компилятор предоставит вашей программе доступ к такой большой памяти, и все будет хорошо с миром.

Если вы скажете компилятору

int x = 9001;
int y = 5;
int a[x][y];

у компилятора нет возможности узнать, сколько памяти вам действительно понадобится во время выполнения, не делая много очень сложного анализа, чтобы отслеживать каждое последнее место, где значения x и y изменены [если есть]. Вместо поддержки таких массивов с переменными размерами С++ и C настоятельно рекомендуют, если вы не хотите, чтобы вы использовали malloc(), чтобы вручную выделить нужное пространство.

TL; DR

int x = 5;
int y = 5;
int **a = malloc(x*sizeof(int*));
for(int i = 0; i < y; i++) {
    a[i] = malloc(sizeof(int*)*y);
}

a теперь представляет собой 2D массив размером 5x5 и будет вести себя так же, как int a [5] [5]. Поскольку вы вручную выделили память, С++ и C требуют, чтобы вы удалили ее вручную...

for(int i = 0; i < x; i++) {
    free(a[i]); // delete the 2nd dimension array
}
free(a); // delete a itself

Ответ 6

Нет, он не обязательно должен быть постоянным, причина, почему его код выше неправильный, заключается в том, что ему нужно включить имя переменной перед объявлением.

int row = 8;
int col= 8;
int x[row][col];

В Xcode, который будет компилироваться и запускаться без каких-либо проблем, в компиляторе M $С++ в .NET он не будет компилироваться, он будет жаловаться, что вы не можете использовать не const-литерал для инициализации массива, размер должен быть известен в время компиляции