Я получаю сообщение об ошибке, когда пытаюсь создать массив из объявленных переменных.
int row = 8;
int col= 8;
int [row][col];
Почему я получаю эту ошибку:
выражение должно иметь постоянное значение.
Я получаю сообщение об ошибке, когда пытаюсь создать массив из объявленных переменных.
int row = 8;
int col= 8;
int [row][col];
Почему я получаю эту ошибку:
выражение должно иметь постоянное значение.
При создании такого массива его размер должен быть постоянным. Если вам нужен массив с динамическим размером, вам нужно выделить память для него в куче, и вам также нужно будет освободить его с помощью 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];
даже не предоставляет имя переменной.
С++ не позволяет использовать непостоянные значения для размера массива. Это так, как оно было разработано.
C99 позволяет размеру массива быть переменной, но я не уверен, что это разрешено для двух измерений. Некоторые компиляторы С++ (gcc) разрешают это как расширение, но вам может потребоваться включить параметр компилятора, чтобы разрешить его.
И я почти пропустил это - вам нужно объявить имя переменной, а не только размеры массива.
Стандарт требует, чтобы длина массива была значением, которое можно вычислить во время компиляции, чтобы компилятор мог выделить достаточно места в стеке. В вашем случае вы пытаетесь установить длину массива на значение, которое неизвестно во время компиляции. Да, я знаю, что кажется очевидным, что он должен быть известен компилятору, но здесь это не так. Компилятор не может делать никаких предположений о содержимом непостоянных переменных. Итак, идите с:
const int row = 8;
const int col= 8;
int a[row][col];
UPD: некоторые компиляторы фактически позволят вам снять это. IIRC, g++ имеет эту функцию. Однако никогда не используйте его, потому что ваш код станет не переносимым для компиляторов.
Вы можете использовать #define в качестве альтернативного решения, которое не вводит вектор и malloc, и вы все еще используете один и тот же синтаксис при определении массива.
#define row 8
#define col 8
in main()
{
int [row][col];
}
Когда вы объявляете переменную как здесь
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
Нет, он не обязательно должен быть постоянным, причина, почему его код выше неправильный, заключается в том, что ему нужно включить имя переменной перед объявлением.
int row = 8;
int col= 8;
int x[row][col];
В Xcode, который будет компилироваться и запускаться без каких-либо проблем, в компиляторе M $С++ в .NET он не будет компилироваться, он будет жаловаться, что вы не можете использовать не const-литерал для инициализации массива, размер должен быть известен в время компиляции