6.19 Массивы переменной длины
В стандарте ISO C99 разрешены автоматические массивы переменной длины, и как расширение GCC принимает их в режиме C90 и в C++. Эти массивы объявляются как и любые другие автоматические массивы, но с длиной, которая не является константным выражением. Память выделяется в момент объявления и освобождается, когда область видимости блока, содержащего объявление, завершается. Например:
FILE *
concat_fopen (char *s1, char *s2, char *mode)
{
char str[strlen (s1) + strlen (s2) + 1];
strcpy (str, s1);
strcat (str, s2);
return fopen (str, mode);
}
Выход из области видимости имени массива (например, с помощью операторов `break` или `return`) освобождает выделенную память. Выход в область видимости массива не разрешен; за это вы получите сообщение об ошибке.
В качестве расширения GCC допускает массивы переменной длины в качестве элементов структуры или объединения. Например:
void
foo (int n)
{
struct S { int x[n]; };
}
Вы можете использовать функцию alloca для получения эффекта, очень похожего на массивы переменной длины. Функция alloca доступна во многих других реализациях C (но не во всех). С другой стороны, массивы переменной длины более элегантны.
Существуют и другие различия между этими двумя методами. Память, выделенная с помощью alloca, существует до возвращения из содержащей ее функции. Память для массива переменной длины освобождается, как только заканчивается область видимости имени массива, если вы также не используете alloca в этой области видимости.
Вы также можете использовать массивы переменной длины в качестве аргументов функций:
struct entry
tester (int len, char data[len][len])
{
/* … */
}
Длина массива вычисляется один раз при выделении памяти и запоминается для области видимости массива, в случае если вы обращаетесь к ней с помощью sizeof.
Если вы хотите передать массив сначала, а длину — потом, вы можете использовать объявление параметра вперед — еще одно расширение GNU.
struct entry
tester (int len; char data[len][len], int len)
{
/* … */
}
` int len ` перед точкой с запятой — это объявление параметра вперед, и оно служит для того, чтобы имя len стало известным при разборе объявления data.
В списке параметров вы можете записать любое количество таких объявлений параметров вперед. Они могут быть разделены запятыми или точками с запятой, но последнее должно заканчиваться точкой с запятой, за которой следуют «реальные» объявления параметров. Каждое объявление вперед должно соответствовать «реальному» объявлению по имени и типу данных. Стандарт ISO C99 не поддерживает объявления параметров вперед.
Далее: Макросы с переменным числом аргументов, Предыдущее: Пустые структуры, Вверх: Расширения C [Оглавление][Индекс]
© Free Software Foundation
Licensed under the GNU Free Documentation License, Version 1.3.
https://gcc.gnu.org/onlinedocs/gcc-7.5.0/gcc/Variable-Length.html