void va_start(va_list argptr, last_parm)
void va_end(va_list argptr)
void va_arg(va_list argptr, type)
Макросы va_arg(), va_start() и va_end() используются совместно для того, чтобы осуществить передачу функции переменного числа параметров. Наиболее общеупотребительным примером использования функции с переменным числом параметров служит printr(). Тип va_list определен в файле stdarg.h.
Общая процедура создания функции, которая имеет переменное число аргументов, заключается в следующем: функция должна иметь один или более известных параметров. Эти известные параметры следуют перед списком переменных параметров. Самый правый известный параметр называется last_parm. Имя last_parm используется в качестве второго параметра в вызове va_start(). Прежде чем осуществлять доступ к какому-либо из переменных параметров, должен быть инициализирован указатель argptr, для чего используется вызов va_start(). После этого параметры возвращаются с помощью вызова функции va_arg() с параметром type, являющимся типом следующего параметра. Наконец, после того, как все параметры прочитаны, перед тем как выйти из функции, необходимо вызвать функцию va_end(), что гарантирует правильное восстановление стека. Если функция va_end() не вызвана, то возникает аварийная ситуация.
Следующая программа использует функцию sum_series() для возврата суммы последовательности чисел. Первый аргумент содержит счетчик числа аргументов, которые будут переданы функции. В данном примере суммируются первые пять элементов последовательности: (1/2)+(1/4)+(1/8)+(1/16) ... Программа выведет результат «0.968750». /* пример аргумента переменной длины - сумма последовательности */ #include <stdio.h> #include <stdarg.h> double sum_series(int, ...); int main(void) { double d; d = sum_series(5, 0.5, 0.25, 0.125, 0.0625, 0.03125); printf("Sum of series is %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; }
