Udostępnij za pośrednictwem


va_arg, va_end, va_start

List argument zmiennej dostępu.

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)

Parametry

  • type
    Typ argumentu do pobrania.

  • arg_ptr
    Wskaźnik do listy argumentów.

  • prev_param
    Parametr poprzedzającego pierwszy argument opcjonalny (tylko ANSI).

Wartość zwracana

va_argZwraca argument bieżące; va_starti va_end nie zwraca wartości.

Uwagi

va_arg, va_end, I va_start makra udostępniają przenośny sposób dostępu do argumentów dla funkcji, gdy funkcja przyjmuje zmienna liczba argumentów.Dostępne są dwie wersje makr: makra, określonych w STDARG.H zgodne ze standardem ANSI C.Makra zdefiniowane w typu VARARGS.H są przestarzałe i pozostają wstecz zgodności.Zostały one zaprojektowane do użytku przed normalizacji ANSI.

Te makra założono, że funkcja przyjmuje stała liczba wymaganych argumentów, następuje zmienna liczba argumentów opcjonalnych.Wymagane argumenty zostały zgłoszone jako zwykłe parametry funkcji i dostępne przez nazwy parametrów.Opcjonalne argumenty są dostępne poprzez makra w STDARG.H lub typu VARARGS.H, ustaw wskaźnik do pierwszego argumentu opcjonalne na liście argumentów, pobierać argumenty z listy i zresetować wskaźnik po zakończeniu przetwarzania argument.

ANSI c standardowe makra, określonych w STDARG.H, są używane w następujący sposób:

  • va_startUstawia arg_ptr do pierwszego opcjonalnego argumentu na liście argumentów przekazanych do funkcji.Argument arg_ptr musi mieć va_list typu.Argument prev_param jest nazwą wymaganego parametru bezpośrednio poprzedzającym pierwszy opcjonalnego argumentu na liście argumentów.Jeśli prev_param jest zadeklarowana z rejestru storage class zachowanie makro jest niezdefiniowane.va_startmuszą być używane przed va_arg jest używany po raz pierwszy.

  • va_argpobiera wartość type z lokalizacji określonej przez arg_ptr i przyrosty arg_ptr wskaż następny argument na liście przy użyciu rozmiaru type do określenia, w której zaczyna się następny argument.va_argmoże być używany dowolną liczbę razy w funkcji do pobierania argumentów z listy.

  • Po pobraniu wszystkich argumentów va_end resetuje wskaźnik, aby NULL.

Uwaga dotycząca języka C++Uwaga dotycząca języka C++

Makra zdefiniowane w typu VARARGS.H są przestarzałe i istnieje wyłącznie do tyłu zgodności.Użyć makra, określonych w STDARGS.H, chyba że użytkownik pracuje z kodu przed standardu ANSI.

Gdy kompilowany z / CLR (kompilacja wspólnej Language Runtime), programy korzystające z tych makr może generować nieoczekiwane wyniki z powodu różnic między systemami typu runtime macierzystych i wspólnego języka.Należy wziąć pod uwagę ten program:

#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*
}

Należy zauważyć, że testit oczekuje, że jej drugi parametr, albo być int lub char*.Argumenty przekazywane są 0xffffffff ( unsigned int, nie int) i NULL (faktycznie int, nie char*).Gdy kompilowany do kodu macierzystego, program generuje dane wyjściowe

-1
(null)

Jednakże gdy kompilowany z /clr:pure, niezgodności typów spowodować, że program wygeneruje wyjątek.Rozwiązaniem jest użycie jawne poświaty:

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

Wymagania

Nagłówek: <stdio.h> i <stdarg.h>

Stare nagłówka: <varargs.h>

Biblioteki

Wszystkie wersje biblioteki uruchomieniowej c.

Przykład

// 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 );
}

Dane wyjściowe

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

Odpowiednik w programie .NET Framework

Klasa System::ParamArrayAttribute

Zobacz też

Informacje

Argument dostępu

inne problemy, _vfprintf_l, vfwprintf, _vfwprintf_l