Почему я не могу создать массив с размером, определяемым глобальной переменной?

Почему массив a не получает инициализацию глобальной переменной size?

#include<stdio.h>

int size = 5;

int main()
{
    int a[size] = {1, 2, 3, 4, 5};
    printf("%d", a[0]);

    return 0;
}

Ошибка компиляции отображается как

объект с переменным размером не может быть инициализирован

По мне, массив должен получить инициализацию size.

И каков будет ответ, если я буду настаивать на использовании глобальной переменной (если это возможно)?

Ответ 1

В C99, 6.7.8/3:

Тип объекта, который должен быть инициализируется массив массивов неизвестный размер или тип объекта, который а не тип массива переменной длины.

6,6/2:

Можно оценить постоянное выражение во время трансляции, а не времени выполнения

6,6/6:

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

6.7.5.2/4:

Если размер является целочисленной константой выражение и тип элемента имеет известный постоянный размер, тип массива не тип массива переменной длины; в противном случае тип массива является тип массива переменной длины.

a имеет тип массива переменной длины, потому что size не является целым постоянным выражением. Таким образом, он не может иметь список инициализаторов.

В C90 нет VLA, поэтому по этой причине код является незаконным.

В С++ также нет VLA, но вы можете сделать size a const int. Это потому, что в С++ вы можете использовать переменные const int в ICE. В C вы не можете.

Предположительно, вы не намеревались a иметь переменную длину, так что вам нужно:

#define size 5

Если вы действительно намеревались a иметь переменную длину, я полагаю, вы могли бы сделать что-то вроде этого:

int a[size];
int initlen = size;
if (initlen > 5) initlen = 5;
memcpy(a, (int[]){1,2,3,4,5}, initlen*sizeof(int));

Или, может быть:

int a[size];
for (int i = 0; i < size && i < 5; ++i) {
    a[i] = i+1;
}

Однако трудно сказать, что "должно" произойти здесь в случае, когда size!= 5. На самом деле не имеет смысла указывать начальное значение фиксированного размера для массива переменной длины.

Ответ 2

Вам не нужно сообщать компилятору, какой размер массив, если вы даете инициализатор. Компилятор будет определять размер, основанный на том, сколько элементов вы инициализируете с помощью.

int a[] = {1,2,3,4,5};

Тогда вы даже можете позволить компилятору рассказать вам размер, получив общий размер массива в байтах sizeof(a) и разделив его на размер одного элемента sizeof(a[0]):

int size = sizeof(a) / sizeof(a[0]);

Ответ 3

Компилятор не может предположить, что значение размера все равно 5 к моменту, когда main() получает контроль. Если вам нужна истинная константа в проекте C старого стиля, используйте:

#define size 5

Ответ 4

Похоже, что ваш компилятор не совместим с C99... говоря о котором, какой компилятор вы используете? Если это gcc, вам нужно передать переключатель "-std = c99".... если вы используете компилятор pre-C99, этот оператор является незаконным, если в этом случае выполните следующее:

int main() { 
   int a[5]={1,2,3,4,5}; 
   printf("%d",a[0]); 
   return 0; 
}

В стандартных компиляторах pre-C99 используйте константу вместо переменной.

Изменить: Вы можете узнать больше о стандарте C99 здесь... и здесь....

Ответ 5

size - это переменная, а C не позволяет вам объявлять ( edit: C99 позволяет вам объявить их, просто не инициализировать их, как вы это делаете) массивы с переменным размером, подобным этому, Если вы хотите создать массив, размер которого является переменной, используйте malloc или сделайте размер постоянным.

Ответ 6

Компилятор должен знать размер массива, объявляя его. Поскольку размер массива не изменяется после его объявления. Если вы поместите размер массива в переменную, вы можете себе представить, что значение этой переменной изменится при выполнении программы. В этом случае компилятор будет вынужден выделить дополнительную память для этого массива. В этом случае это невозможно, так как массив представляет собой статическую структуру данных, выделенную в стеке. Я надеюсь, что это поможет.

Ответ 7

#include<stdio.h> 

/* int size=5; */
#define size 5 /* use this instead*/
/*OR*/
int a[size]={1,2,3,4,5};  /* this*/

int main() 
{ 
    int a[size]={1,2,3,4,5}; 
    printf("%d",a[0]); 
    return 0; 
} 

int size означает, что size является переменной , а C не позволяет массивы переменной size.

Я использую VS2008, где используется

const int size=5;  

позволяет

int a[size]={1,2,3,4,5};