#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 определен в заголовке <stdarg.h>.
Общая процедура создания функции, которая может принимать переменное количество аргументов, такова:
Функция должна иметь по крайней мере один известный параметр (может и больше), указываемый до переменного списка параметров. (Такие параметры называются также обязательными, а параметры, следующие за ними — необязательными.) Крайний правый известный параметр называется last_parm. (Он предшествует первому необязательному параметру.) Его имя используется в качестве второго параметра в обращении к макросу va_start(). Чтобы получить доступ к любому дополнительному параметру, сначала необходимо инициализировать указатель-аргумент argptr[1], обратившись к макросу va_start(). (Иными словами, необходимо выполнить вызов va_start(argptr, <имя last_parm>).) После этого значения параметров возвращаются в результате вызова макроса va_arg(). В качестве второго аргумента этого макроса (соответствующего параметру type), нужно указать тип следующего параметра[2]. Наконец, после прочтения всех параметров до возвращения из функции необходимо вызвать макрос 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()
[1]Он должен быть объявлен, например, так:
va_list argptr;
[2]Ну где вы видели функцию, которой в качестве аргумента передается служебное слово? Конечно, это возможно именно потому, что va_arg() — макрос, а не функция языка С. Кроме того, посмотрите на описание type
va_arg(va_list argptr, type);
Какой же компилятор позволит вам так описывать функцию?!