Udostępnij za pośrednictwem


va_arg, va_copy, va_end, va_start

Listy uzyskuje dostęp do zmiennej argument.

type va_arg(
   va_list arg_ptr,
   type 
);
void va_copy(
   va_list dest,
   va_list src
); // (ISO C99 and later)
void va_end(
   va_list arg_ptr 
);
void va_start(
   va_list arg_ptr,
   prev_param 
); // (ANSI C89 and later)
void va_start(
   arg_ptr 
);  // (Pre-ANSI C89 standardization version)

Parametry

  • type
    Typ argumentu do pobrania.

  • arg_ptr
    Wskaźnik na listę argumentów.

  • dest
    Wskaźnik do listy argumentów zainicjowana zsrc

  • src
    Wskaźnik, aby zainicjować listę argumentów, aby skopiować do dest.

  • prev_param
    Parametr, który poprzedza pierwszy argument opcjonalny.

Wartość zwracana

va_argZwraca bieżący argument.va_copy, va_start i va_end nie zwraca wartości.

Uwagi

va_arg, va_copy, va_end, I va_start makra zapewniają przenośne sposób uzyskać dostęp do argumentów do funkcji, gdy funkcja przyjmuje zmiennej liczbie argumentów.Dostępne są dwie wersje makr: makra zdefiniowane w STDARG.H odpowiadają C99 ISO standardowych; makra zdefiniowane w VARARGS.H są przestarzałe, ale są zachowywane dla zgodności z poprzednimi wersjami z kodem, który został napisany przed standardowych kompilatorem C89 ANSI.

Te makra założono, że funkcja przyjmuje stałą liczbę wymaganych argumentów, następuje zmienna liczba argumentów opcjonalnych.Wymagane argumenty są deklarowane jako zwykłe parametry funkcji i mogą być udostępniane za pośrednictwem nazwy parametrów.Opcjonalne argumenty są dostępne za pośrednictwem makra w STDARG.H (lub VARARGS.H dla kodu, który został napisany przed standardu ANSI kompilatorem C89), który ustawia wskaźnik do pierwszego argumentu opcjonalne na liście argumentów pobiera argumenty z listy, a po zakończeniu przetwarzania argument resetuje wskaźnik.

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

  • va_startUstawia arg_ptr do pierwszego argumentu opcjonalne na liście argumentów przekazanych do funkcji.Argument arg_ptr musi być va_list typu.Argument prev_param jest nazwą wymagany parametr, który bezpośrednio na liście argumentów poprzedza pierwszy argument opcjonalny.Jeśli prev_param jest zadeklarowana za pomocą klasy magazynu rejestru, zachowanie makro jest niezdefiniowane.va_startmuszą być używane przed va_arg jest używany po raz pierwszy.

  • va_argpobiera wartość type z lokalizacji, w której wyraża się przez arg_ptroraz przyrostów, arg_ptr wskaż polecenie Następny argument na liście przy użyciu rozmiaru type do określenia, gdzie zaczyna się następny argument.va_argmoże być używana dowolną liczbę razy w funkcji do pobierania argumentów z listy.

  • va_copyTworzy kopię listy argumentów w jego bieżącym stanie.src Parametr musi być już zainicjowany z va_start; został zaktualizowany z va_arg wywołuje, ale musi być nie Resetuj z va_end.Następny argument, że pobrana przez va_arg z dest jest taka sama jak dalej argument, który jest pobierany z src.

  • Po pobraniu wszystkich argumentów va_end resetuje wskaźnik, aby wartości NULL.va_endmusi być wywołany w każdej listy argumentów, który jest inicjowany z va_start lub va_copy zanim funkcja zwraca.

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

Makra w VARARGS.H są przestarzałe i są zachowywane tylko dla wstecznej zgodności z kodem, który został napisany przed standardu ANSI kompilatorem C89.We wszystkich innych przypadkach należy użyć makra z STDARGS.H.

Kiedy są kompilowane za pomocą /clr (Kompilacja środowiska uruchomieniowego języka wspólnego), programy korzystające z tych makr może generować nieoczekiwane rezultaty, ze względu na różnice między macierzystym i wspólnego języka wspólnego (CLR) typu systemów.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 drugi parametr może przyjąć formę int lub char*.Argumenty przekazywane są 0xffffffff ( unsigned int, nie int) i NULL (faktycznie int, nie char*).Gdy program jest kompilowany do kodu macierzystego, daje to wyjście:

  
  

Jednakże, kiedy program jest kompilowana za pomocą /clr:pure, niezgodności typu spowodować wygenerowanie wyjątku.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 >

Niezalecane nagłówek:<varargs.h>

Biblioteki

Wszystkie wersje Bibliotek uruchomieniowych C.

Przykład

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

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

double deviation(int first, ...);

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

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

    /* Call with just -1 terminator. */
    printf("Deviation is: %f\n", deviation(-1));
}

/* Returns the standard deviation of a variable list of integers. */
double deviation(int first, ...)
{
    int count = 0, i = first;
    double mean = 0.0, sum = 0.0;
    va_list marker;
    va_list copy;

    va_start(marker, first);     /* Initialize variable arguments. */
    va_copy(copy, marker);       /* Copy list for the second pass */
    while (i != -1)
    {
        sum += i;
        count++;
        i = va_arg(marker, int);
    }
    va_end(marker);              /* Reset variable argument list. */
    mean = sum ? (sum / count) : 0.0;

    i = first;                  /* reset to calculate deviation */
    sum = 0.0;
    while (i != -1)
    {
        sum += (i - mean)*(i - mean);
        i = va_arg(copy, int);
    }
    va_end(copy);               /* Reset copy of argument list. */
    return count ? sqrt(sum / count) : 0.0;
}

Dane wyjściowe

  

Odpowiednik w programie .NET Framework

Klasa System::ParamArrayAttribute

Zobacz też

Informacje

Dostęp do argumentów

vfprintf, _vfprintf_l, vfwprintf, _vfwprintf_l