Функция va_arg, va_start, va_end, va_copy

#include <stdarg.h>
type va_arg(va_list argptr, type);
void va_copy(va_list target, va_list source);
void va_end(va_list argptr);
void va_start(va_list argptr, last_parm);
Макрос va_copy() добавлен в версии С99.

Для передачи функции переменного числа аргументов совместно используются макросы va_arg, va_start и va_end. Самым распространенным примером функции, которая принимает переменное число аргументов, является функция printf(). Тип va_list определен в заголовке .

Общая процедура создания функции, которая может принимать переменное количество аргументов, такова:

Функция должна иметь по крайней мере один известный параметр (может и больше), указываемый до переменного списка параметров. (Такие параметры называются также обязательными, а параметры, следующие за ними — необязательными.) Крайний правый известный параметр называется last_parm. (Он предшествует первому необязательному параметру.) Его имя используется в качестве второго параметра в обращении к макросу va_start(). Чтобы получить доступ к любому дополнительному параметру, сначала необходимо инициализировать указатель-аргумент argptr, обратившись к макросу va_start(). (Иными словами, необходимо выполнить вызов va_start(argptr, <имя last_parm>).) После этого значения параметров возвращаются в результате вызова макроса va_arg(). В качестве второго аргумента этого макроса (соответствующего параметру type), нужно указать тип следующего параметра. Наконец, после прочтения всех параметров до возвращения из функции необходимо вызвать макрос va_end(), чтобы гарантировать корректное восстановление стека. Если макрос va_end() вызван не будет, высока вероятность аварийного отказа программы.

Макрос va_copy() копирует список аргументов, обозначенный параметром target, в объект, обозначенный параметром source.


Пример

Эта программа использует функцию sum_series(), возвращающую сумму последовательности чисел. Первый аргумент содержит число дополнительно передаваемых аргументов. В этом примере программа суммирует первые пять слагаемых суммы
1 1 1 1 1
- + - + - + -- + ... + --
2 4 8 16 2N
Будет выведено

0.968750
#include <stdio.h>
#include <stdarg.h>

double sum_series(int num, ...);

/* Пример переменного числа аргументов - сумма последовательности. */
int main(void)
{
double d;

d = sum_series(5, 0.5, 0.25, 0.125, 0.0625, 0.03125);

printf("Сумма последовательности %f.\n", d);

return 0;
}

double sum_series(int num, ...)
{
double sum=0.0, t;
va_list argptr;

/* Инициализация argptr */
va_start(argptr, num);

/* сумма последовательности */
for( ; num; num--) {
t = va_arg(argptr, double); /* получить следующий аргумент */
sum += t;
}

/* выполнение корректного выхода */
va_end(argptr);
return sum;
}



Зависимые функции

vprintf() ( http://c2p.ru/c/vprintf.html )

Оригинал новости «Функция va_arg, va_start, va_end, va_copy»  - http://c2p.ru/c/va_arg-va_start-va_end-va_copy.html
«Программирование на C, C++, Java, .NET»  - http://c2p.ru/index.php