Sdílet prostřednictvím


va_arg, va_copy, va_end, va_start

Přistupuje k seznamům argumentů proměnných.

Syntaxe

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, který se má načíst.

arg_ptr
Ukazatel na seznam argumentů

dest
Ukazatel na seznam argumentů, ze které se mají inicializovat src

src
Ukazatel na inicializovaný seznam argumentů pro zkopírování do dest.

prev_param
Parametr, který předchází prvnímu volitelnému argumentu.

Vrácená hodnota

va_arg vrátí aktuální argument. va_copyva_start a va_end nevrací hodnoty.

Poznámky

Makra va_arga , va_endva_copyva_start poskytují přenosný způsob, jak získat přístup k argumentům funkce, když funkce přebírá proměnlivý počet argumentů. Existují dvě verze maker: Makra definovaná standardem STDARG.H ISO C99 jsou zastaralá, VARARGS.H ale zachovají se kvůli zpětné kompatibilitě s kódem napsaným před standardem ANSI C89.

Tato makra předpokládají, že funkce přebírá pevný počet povinných argumentů následovaných proměnným počtem volitelných argumentů. Požadované argumenty jsou deklarovány jako běžné parametry funkce a lze k němu přistupovat prostřednictvím názvů parametrů. Volitelné argumenty jsou přístupné prostřednictvím maker v STDARG.H makrech (nebo VARARGS.H pro kód napsaný před standardem ANSI C89), který nastaví ukazatel na první volitelný argument v seznamu argumentů, načte argumenty ze seznamu a resetuje ukazatel při dokončení zpracování argumentu.

Standardní makra jazyka C definovaná v STDARG.H:

  • va_start nastaví arg_ptr první volitelný argument v seznamu argumentů předaných funkci. arg_ptr Argument musí mít va_list typ. prev_param Argument je název požadovaného parametru, který bezprostředně předchází prvnímu volitelnému argumentu v seznamu argumentů. Pokud prev_param je deklarována pomocí třídy úložiště registru, chování makra není definováno. va_start musí být použit dříve, než va_arg se použije poprvé.

  • va_arg načte hodnotu type z umístění, které je dáno parametrem arg_ptr, a navýší arg_ptr odkaz na další argument v seznamu pomocí velikosti type určující, kde začíná další argument. va_arg funkci lze použít libovolný početkrát k načtení argumentů ze seznamu.

  • va_copy vytvoří kopii seznamu argumentů v aktuálním stavu. Parametr src již musí být inicializován va_startpomocí ; mohl být aktualizován voláním va_arg , ale nesmí být resetován pomocí va_end. Další argument, který je načten z va_argdest , je stejný jako další argument načtený z src.

  • Po načtení va_end všech argumentů obnoví ukazatel na NULLhodnotu . va_end musí být volána v každém seznamu argumentů, který je inicializován s va_start funkcí nebo va_copy před vrácením funkce.

Poznámka

Makra v nástroji VARARGS. H jsou zastaralé a uchovávají se pouze kvůli zpětné kompatibilitě s kódem napsaným před standardem ANSI C89. Ve všech ostatních případech použijte makra ve SDARGS.H.

Při kompilaci pomocí /clr (Common Language Runtime Compilation) můžou programy, které používají tato makra, generovat neočekávané výsledky kvůli rozdílům mezi systémy typů CLR (Native And Common Language Runtime). Zvažte tento 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*
}

Všimněte si, že očekává, že testit jeho druhý parametr bude buď an, int nebo a char*. Předané argumenty jsou 0xffffffff (an unsigned int, nikoli int) a NULL (ve skutečnosti , intnikoli ).char* Když je program zkompilován pro nativní kód, vytvoří tento výstup:

-1

(null)

Požadavky

Záhlaví:<stdio.h> a <stdarg.h>

Zastaralá hlavička:<varargs.h>

Knihovny

Všechny verze knihoven runtime jazyka C.

Příklad

// 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

Viz také

Přístup k argumentům
vfprintf, _vfprintf_l, vfwprintf, _vfwprintf_l