va_arg, va_copy, va_end, va_start

Uzyskuje dostęp do list zmiennych-argumentów.

Składnia

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
);  // (deprecated Pre-ANSI C89 standardization version)

Parametry

type
Typ argumentu do pobrania.

arg_ptr
Wskaźnik do listy argumentów.

dest
Wskaźnik do listy argumentów do zainicjowania z src

src
Wskaźnik do zainicjowanej listy argumentów, aby skopiować do destelementu .

prev_param
Parametr poprzedzający pierwszy opcjonalny argument.

Wartość zwracana

va_arg Zwraca bieżący argument. va_copyva_start i va_end nie zwracają wartości.

Uwagi

Makra va_arg, va_copy, va_endi va_start zapewniają przenośny sposób uzyskiwania dostępu do argumentów do funkcji, gdy funkcja przyjmuje zmienną liczbę argumentów. Istnieją dwie wersje makr: makra zdefiniowane zgodnie STDARG.H ze standardem ISO C99; makra zdefiniowane w VARARGS.H pliku są przestarzałe, ale są zachowywane w celu zachowania zgodności z poprzednim kodem, który został napisany przed standardem ANSI C89.

Te makra zakładają, że funkcja przyjmuje stałą liczbę wymaganych argumentów, a następnie zmienną liczbę argumentów opcjonalnych. Wymagane argumenty są deklarowane jako zwykłe parametry funkcji i mogą być dostępne za pośrednictwem nazw parametrów. Opcjonalne argumenty są dostępne za pośrednictwem makr w STDARG.H pliku (lub VARARGS.H dla kodu, który został napisany przed standardem ANSI C89), który ustawia wskaźnik na pierwszy opcjonalny argument na liście argumentów, pobiera argumenty z listy i resetuje wskaźnik po zakończeniu przetwarzania argumentów.

Standardowe makra języka C zdefiniowane w STDARG.Hsystemie są używane w następujący sposób:

  • va_start ustawia arg_ptr na pierwszy opcjonalny argument na liście argumentów przekazywanych do funkcji. Argument arg_ptr musi mieć va_list typ . Argument prev_param jest nazwą wymaganego parametru, który bezpośrednio poprzedza pierwszy opcjonalny argument na liście argumentów. Jeśli prev_param zostanie zadeklarowana z klasą rejestru magazynu, zachowanie makra jest niezdefiniowane. va_start należy użyć przed va_arg pierwszym zastosowaniem.

  • va_arg Pobiera wartość type z lokalizacji podanej przez arg_ptrparametr i zwiększa arg_ptr , aby wskazać następny argument na liście przy użyciu rozmiaru type , aby określić, gdzie rozpoczyna się następny argument. va_arg Można użyć dowolnej liczby razy w funkcji, aby pobrać argumenty z listy.

  • va_copy Tworzy kopię listy argumentów w bieżącym stanie. Parametr src musi być już zainicjowany za pomocą va_startpolecenia . Być może został zaktualizowany za pomocą va_arg wywołań, ale nie może zostać zresetowany za pomocą polecenia va_end. Następny argument pobrany przez va_argdest program jest taki sam jak następny argument pobrany z elementu src.

  • Po pobraniu va_end wszystkich argumentów zresetuj wskaźnik na NULL. va_end Musi być wywoływana na każdej liście argumentów zainicjowanej za pomocą va_start funkcji lub va_copy przed zwróceniem funkcji.

Uwaga

Makra w usłudze VARARGS. H są przestarzałe i są zachowywane tylko w celu zapewnienia zgodności z poprzednimi wersjami kodu, który został napisany przed standardem ANSI C89. We wszystkich innych przypadkach użyj makr w pliku STDARGS.H.

Gdy są one kompilowane przy użyciu /clr (kompilacja środowiska uruchomieniowego języka wspólnego), programy korzystające z tych makr mogą generować nieoczekiwane wyniki z powodu różnic między systemami typów środowiska uruchomieniowego natywnego i wspólnego języka (CLR). Rozważmy 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);
    }

    va_end(argptr);
}

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

Zwróć uwagę, że testit jego drugi parametr ma być parametrem intchar*lub . Przekazywane argumenty są 0xffffffff (a unsigned int, a nie int) i NULL (faktycznie int, a nie char*). Gdy program jest kompilowany dla kodu natywnego, generuje następujące dane wyjściowe:

-1

(null)

Wymagania

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

Przestarzały nagłówek:<varargs.h>

Biblioteki

Wszystkie wersje bibliotek czasu wykonywania języka 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;
}
Deviation is: 0.816497
Deviation is: 2.236068
Deviation is: 0.000000

Zobacz też

Dostęp do argumentów
vfprintf, _vfprintf_l, vfwprintf, _vfwprintf_l