Выражение должно иметь константное значение
Visual Studio выдает ошибку "выражение должно иметь константное значение" когда задается массив размера N. В чем проблема и как ее решить?
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void generateNums(int *array, int arrayLength) {
srand(time(NULL));
for (int i = 0; i < arrayLength; i++) {
array[i] = rand()%1001;
}
}
void numsShifting(int *array, int arrayLength) {
int temp;
for (int i = 0; i < 6; i++) {
temp = array[arrayLength - 1];
for (int i = arrayLength - 1; i > 0; i--) {
array[i] = array[i - 1];
}
array[0] = temp;
}
}
void printArray(int *array, int arrayLength) {
for (int i = 0; i < arrayLength; i++) {
printf("%d\n", array[i]);
}
}
int main() {
int N;
printf("Please write size of array, which you want to shift\n");
scanf("%d", &N);
int array[N];
generateNums(array, N);
printf("Input array:\n");
printArray(array, N);
numsShifting(array, N);
printf("Result array:\n");
printArray(array, N);
return 0;
}
Ответы (2 шт):
Проблема в компиляторе. Он вам говорит, что размер должен быть фиксирован во время компиляции, то есть вот так: int array[10];.
Это требование есть в С++, а в C нет. Разработчикам MSVC чистый C без ++ похоже не очень интересен, и они решили не заморачиваться.
Эту фичу добавили в С99, а после того, как в MSVC не стали добавлять поддержку, стандарт С опять поправили (в С11), и теперь поддержка массивов переменной длины стала необязательной.
Варианты такие:
- Поменять компилятор - на Clang или GCC (которые удобнее всего установить из MSYS2).
- Использовать
malloc()- это сложнее. - Написать размер массива с запасом - несерьезно.
- Перейти на С++ и использовать
std::vector.
Одну строку изменить
scanf("%d", &N);
// Если в строке с `malloc` компилятор без (int)malloc не компилирует -
// значит, на самом деле вы компилируете код как С++, а не как С!!
int * array = malloc(N*sizeof(int));
generateNums(array, N);
printf("Input array:\n");
одну добавить
printArray(array, N);
free(array);
return 0;
Но кроме того, как я понимаю, вы шесть раз пытаетесь выполнить сдвиг на 1 значение? но это по-хорошему делается не так, а двумя разворотами. Конечно, 6 — значение небольшое, ну а если массив в 10000 элемментов и сдвигать на 1000? у вас будет десять миллионо переносов...
Кстати, формально такое можно делать и все у вас в конкретном коде будет работать
for (int i = 0; i < 6; i++) {
temp = array[arrayLength - 1];
for (int i = arrayLength - 1; i > 0; i--) {
но ведь использование одного и того же имени во внешнем и вложенном циклах несколько запутывает, и в более серьезном коде может приводить и к ошибкам...