Поделиться через


va_arg, va_end, va_start

Списки аргументов переменной доступа.

type va_arg(
   va_list arg_ptr,
   type 
);
void va_end(
   va_list arg_ptr 
);
void va_start(
   va_list arg_ptr,
   prev_param 
); // (ANSI version)
void va_start(
   arg_ptr 
);  // (Pre-ANSI-standardization version)

Параметры

  • type
    Тип аргумента для извлечения.

  • arg_ptr
    Указатель на список аргументов.

  • prev_param
    Параметр предшествующего первого необязательного аргумента (ANSI).

Возвращаемое значение

va_argВозвращает текущий аргумент; va_startи va_end не возвращают значений.

Заметки

va_arg, va_end, И va_start макросы предоставляют портативный способ доступа к функции аргументов, если функция принимает переменное число аргументов.Доступны две версии макросы: макросы, определенные в STDARG.H соответствовать стандарту ANSI C.Макросы, определенные в VARARGS.H устарели и остаются для обратной совместимости.Они предназначены для использования до стандартизации ANSI.

Эти макросы предполагается, что функция принимает определенное число обязательных аргументов, следуют переменное число необязательных аргументов.Необходимые аргументы должны быть объявлены как обычные параметры функции и может осуществляться с помощью имен параметров.Необязательные аргументы можно открыть с помощью макросов STDARG.H или VARARGS.H значение указателя первого необязательный аргумент в списке аргументов, извлечь из списка аргументов и сбрасывать указатель после завершения обработки аргументов.

Макросы стандартных ANSI C, определенный в STDARG.H, используются следующим образом:

  • va_startЗадает arg_ptr на первый необязательный аргумент в списке аргументов, переданных функции.Аргумент arg_ptr должен иметь va_list типа.Аргумент prev_param — это имя обязательного параметра, непосредственно перед первым необязательный аргумент в списке аргументов.Если prev_param объявляется с помощью класса хранения регистров макрос поведение не определено.va_startнеобходимо использовать перед va_arg используется в первый раз.

  • va_argИзвлекает значение из type из местоположения, заданного параметром arg_ptr и увеличивает arg_ptr на следующий аргумент в списке, используя размер type для определения начала следующего аргумента.va_argможно использовать любое число раз в функции извлечения из списка аргументов.

  • После получения всех аргументов va_end сбрасывает указатель на значение NULL,.

Примечание C++Примечание C++

Макросы, определенные в VARARGS.H являются устаревшими и существует исключительно для обратной совместимости.Используйте макросы, определенные в STDARGS.H, если вы не работаете с кодом перед стандарт ANSI.

При компиляции с /clr (компиляция CLR), из-за различий в машинном коде и систем типов во время выполнения программы, использующие эти макросы могут возникать непредвиденные результаты.Рассмотрим эту программу.

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

void testit ( int i, ...)
{
   va_list argptr;
   va_start(argptr, i);

   if ( i == 0 ) {
      int n = va_arg( argptr, int );
      printf( "%d\n", n );
   } else {
      char *s = va_arg( argptr, char* );
      printf( "%s\n", s);
   }
}

int main()
{
   testit( 0, 0xFFFFFFFF ); // 1st problem: 0xffffffff is not an int
   testit( 1, NULL );       // 2nd problem: NULL is not a char*
}

Обратите внимание, что testit ожидает, что его второй параметр должен быть int или char*.Передаваемые аргументы, 0xffffffff ( unsigned int, а не int) и NULL (фактически int, а не char*).При компиляции машинного кода, программа создает выходные данные

-1
(null)

Однако при компиляции с /clr:pure, несоответствие типа к программе для создания исключения.Решением является использование явного приведения:

int main()
{
   testit( 0, (int)0xFFFFFFFF ); // cast unsigned to int
   testit( 1, (char*)NULL );     // cast int to char*
}

Требования

Заголовок: <stdio.h> и <stdarg.h>

Старый заголовок: <varargs.h>

Библиотеки

Все версии библиотеки времени выполнения c.

Пример

// crt_va.c
/* The program below illustrates passing a variable
 * number of arguments using the following macros:
 *      va_start            va_arg              va_end
 *      va_list
 */

#include <stdio.h>
#include <stdarg.h>
int average( int first, ... );

int main( void )
{
   /* Call with 3 integers (-1 is used as terminator). */
   printf( "Average is: %d\n", average( 2, 3, 4, -1 ) );

   /* Call with 4 integers. */
   printf( "Average is: %d\n", average( 5, 7, 9, 11, -1 ) );

   /* Call with just -1 terminator. */
   printf( "Average is: %d\n", average( -1 ) );
}

/* Returns the average of a variable list of integers. */
int average( int first, ... )
{
   int count = 0, sum = 0, i = first;
   va_list marker;

   va_start( marker, first );     /* Initialize variable arguments. */
   while( i != -1 )
   {
      sum += i;
      count++;
      i = va_arg( marker, int);
   }
   va_end( marker );              /* Reset variable arguments.      */
   return( sum ? (sum / count) : 0 );
}

Output

Average is: 3
Average is: 8
Average is: 0

Эквивалент в .NET Framework

Класс System::ParamArrayAttribute

См. также

Ссылки

Доступ аргумента

vfprintf, _vfprintf_l, vfwprintf, _vfwprintf_l