Инициализация происходит только один раз, когда вы создаете массив:
int foo[] = {0,1,2,3,4}; // creates a 5-element array of int and
// initializes it
После того, как массив был определен, вы можете назначить отдельным элементам :
foo[0] = 5;
foo[1] = 4;
foo[2] = 3;
foo[3] = 2;
foo[4] = 1;
но вы не можете назначить сам массив;IOW, вы не можете написать что-то вроде
foo = {5,4,3,2,1};
Однако вы можете использовать memcpy
для копирования содержимого одного массива в другой:
int foo[5];
int bar[5] = {1,2,3,4,5};
int i;
memcpy(foo, bar, sizeof bar); // Copies *contents* of bar to foo
for (i = 0; i < sizeof foo / sizeof *foo; i++)
printf("foo[%d] = %d\n", i, foo[i]);
Точно так же массив, созданный таким образом, не может быть изменен;его размер фиксируется на момент объявления.В C89 и более ранних версиях размер массива должен быть известен во время компиляции - либо путем указания размера с помощью константы времени компиляции (целочисленное выражение или макрос, который расширился до целочисленного выражения), либо с помощью инициализатора, такого как выше,из которого вычисляется размер массива.
C99 представил массивы переменной длины , которые могут быть объявлены с использованием значения времени выполнения, например:
void foo(int x)
{
int arr[x];
...
}
Обратите внимание, что, как и обычные массивы, VLA не могутизменить размер после того, как они были определены.
В качестве альтернативы, вы можете динамически распределять массив с помощью malloc
, хотя вы не можете инициализировать его описанным выше способом:
int *foo = malloc(sizeof *foo * N); // where N is the number of elements
Вы все еще можете назначитьдля отдельных элементов:
foo[0] = 5;
foo[1] = 4;
foo[2] = 3;
...
или вы можете использовать memcpy
, как показано выше.Обратите внимание, что вы должны помнить free
массив, когда вы закончите:
free(foo);
Массивы, созданные таким образом можно изменить , используя realloc
:
int *tmp = realloc(foo, sizeof *foo * NEW_NUMBER_OF_ELEMENTS);
if (tmp)
foo = tmp;
Почему бы просто не присвоить результат realloc
обратно foo
?Если операция realloc
завершится неудачно, она вернет NULL.Если это происходит и мы присваиваем результат обратно foo
, мы теряем отслеживание памяти, которую мы уже выделили, что приводит к утечке памяти.
C99 ввел синтаксис литерала массива;Вы можете написать что-то вроде
int *foo = (int[]){1,2,3,4,5};
и затем индексировать в foo
как массив:
printf("foo[%d] = %d\n", i, foo[i]);
, хотя я почти уверен, что не может изменитьсодержимое foo[i]
, аналогично тому, как попытка изменить содержимое строкового литерала не определена (хотя я не нашел главы и стиха об этом).