va_arg, va_end, va_start

Функция            Создают список аргументов.

Синтаксис          #include 
                   void va_start(va_list param, lastfix);
                   type va_arg(va_list param, type);
                   void va_end(va_list param);

Файл, содержащий   stdarg.h
прототип

Описание           Некоторые СИ-функции, такие как vfprintf и
                   vprintf, принимают переменный список аргументов,
                   в отличие от функций, имеющих фиксированное число
                   аргументов. Макрокоманды семейства va_... обеспе-
                   чивают простой путь доступа к данным спискам ар-
                   гументов. Они используются для перебора аргумен-
                   тов в том случае, когда вызываемая функция не со-
                   общает номер и тип передаваемого аргумента. В за-
                   головочном файле stdarg.h объявлен один тип пере-
                   менного списка аргументов (va_list), и три макро-
                   команды (va_start, va_arg, va_end).

                             Список va_list.

                   Данный массив содержит информацию, требуемую
                   va_arg и va_end. При вызове функции с переменным
                   списком аргументов, объявляется переменная param
                   с типом va_list.

                   va_start
                   Данная подпрограмма (применяемая как макрокоман-
                   да) устанавливает аргумент param в качестве ука-
                   зателя на первый аргумент, передаваемый функции.
                   Заметим, что va_start должна вызываться перед
                   va_arg или va_end. Функция va_start использует
                   два аргумента: param и lastfix (смысл аргумента
                   param объяснен выше в абзаце, посвященном
                   va_list); lastfix - это имя последнего фиксиро-
                   ванного параметра, передаваемого вызванной функ-
                   ции.

                   va_arg
                   Данная подпрограмма, также используемая, как мак-
                   рокоманда, расширяется до выражения, имеющего тот
                   же тип и значение, что и следующий передаваемый
                   аргумент (один из переменных аргументов). Пара-
                   метр param в подпрограмме va_arg должен быть тем
                   же самым param, который инициализирует подпрог-
                   рамма va_start.

                   По умолчанию вы можете использовать с va_arg
                   char, unsigned char или float.

                   Когда va_arg используется первый раз, она возвра-
                   щает первый в списке аргумент. При каждом после-
                   дующем использовании va_arg возвращает следующий
                   по порядку аргумент в списке. Это выполняется
                   посредством обращения к param, и затем присвоения
                   param адреса следующего аргумента. Для этого ис-
                   пользуется параметр type. Каждый успешный вызов
                   подпрограммы va_arg переадресовывает param на
                   следующий аргумент в списке.

                   va_end
                   Данная макрокоманда способствует нормальному воз-
                   врату вызываемой функции. Макрокоманда va_end мо-
                   жет модифицировать param таким образом, что он не
                   сможет быть использован до вызова va_start.
                   va_end должна быть вызвана после того, как функ-
                   ция va_arg прочтет все аргументы; попытка сделать
                   иначе вызовет непредсказуемое поведение вашей
                   программы.

Возвращаемое       Функции va_start и va_end не имеют возвращаемых
значение           значений; va_arg возвращает текущий аргумент в
                   списке (тот, который адресуется с помощью param).

Переносимость      va_arg, va_start, va_end поддерживается на сис-
                   темах UNIX.

Смотрите также      Функции v..scanf v.. printf


Пример:

#include 
#include 
/* вычисляет сумму, завершаемого 0 списка */
void sum(char *msg, ...)
{
   int total = 0;
   va_list ap;
   int arg;
   va_start(ap, msg);
   while ((arg = va_arg(ap,int)) != 0) {
        total += arg;
   }
   printf(msg, total);
}

int main(void)
{
      sum("Сумма 1+2+3+4 = %d\n", 1,2,3,4,0);
}

Результат программы

Сумма 1+2+3+4 = 10

Пример 2:

#include 
#include 

void error(char *format,...)
{
   va_list argptr;
   print("error: ");
   va_start(argptr, format);
   vprintf(format, argptr);
   va_end(argptr);
}

int main(void)
{
   int value = -1;
   error("this is just an error message\n");
   error("invalid value %d encountered\n", value);
}

Результат программы:

error: this is just an error message
error: invalid value -1 encountered