6.20 Массивы переменной длины
Автоматические массивы переменной длины разрешены в 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);
}
Выход за пределы области видимости имени массива или прерывание выполнения в этой области освобождает выделенную память. Вход в область видимости не разрешен; за это будет выведено сообщение об ошибке.
В качестве расширения 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-12.2.0/gcc/Variable-Length.html