Sdílet prostřednictvím


va_arg, va_copy, va_end, va_start

Seznamy přístupů proměnné 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 k načtení.

  • arg_ptr
    Ukazatel na seznam argumentů.

  • dest
    Ukazatel na seznam argumentů nelze inicializovat zsrc

  • src
    Ukazatel inicializovat seznam argumentů, které chcete zkopírovat do dest.

  • prev_param
    Parametr, který předchází první nepovinný argument.

Vrácená hodnota

va_argVrátí aktuální argument.va_copy, va_start a va_end není vrácené hodnoty.

Poznámky

va_arg, va_copy, va_end, A va_start makra umožňují přenosný přístup argumenty na funkci, je-li funkce přijímá proměnný počet argumentů.Existují dvě verze maker: makra, které jsou definovány v STDARG.H v souladu s normou, ISO C99 Makra definovaná v VARARGS.H jsou zastaralé, ale je zachována z důvodu zpětné kompatibility s kódem, který byl napsán před kompilátorem C89 ANSI standardní.

Tato makra se předpokládá, že funkce má pevný počet požadovaných argumentů, následuje proměnlivý počet nepovinných argumentů.Požadované argumenty jsou deklarovány jako běžné parametry funkce a lze přistupovat prostřednictvím názvy parametrů.Volitelné argumenty jsou přístupné prostřednictvím makra v STDARG.H (nebo VARARGS.H pro kód, který byl napsán před kompilátorem C89 ANSI standard), který nastaví ukazatel na první volitelný argument v seznamu argumentů načte ze seznamu argumentů a obnoví ukazatel po dokončení zpracování argumentu.

C standardní maker, definovaných v STDARG.H, se používají následujícím způsobem:

  • va_startNastaví arg_ptr první volitelný argument v seznamu argumentů, který je předán do funkce.Argument arg_ptr musí mít va_list typu.Argument prev_param je název povinný parametr, který bezprostředně předchází první nepovinného argumentu v seznamu argumentů.Pokud prev_param je deklarována pomocí třídy úložiště rejstříku jeho chování není definováno.va_startmusí být použit před va_arg je použit poprvé.

  • va_argnačte hodnotu type z oblasti, která je dána arg_ptra zvýší arg_ptr přejděte na další argument v seznamu pomocí velikost type k určení, kdy začne další argument.va_argmůže být použit libovolný počet ve funkci načíst ze seznamu argumentů.

  • va_copyVytvoří kopii seznamu argumentů v aktuálním stavu.src Parametr musí být již inicializován s va_start; je pravděpodobně byly aktualizovány s va_arg volá, ale nesmí obnovit s va_end.Další argument, který je získán pomocí va_arg z dest je stejný jako další argument, který je získán z src.

  • Po načtení všech argumentů va_end obnoví ukazatel na NULL.va_endmusí být volána pro každý argument seznam, který je inicializován s va_start nebo va_copy dříve, než se vrátí.

Poznámka k jazyku C++Poznámka k jazyku C++

Makra v VARARGS.H jsou zastaralé a jsou zachovány pouze pro zpětnou kompatibilitu s kódem, který byl napsán před standardu ANSI kompilátorem C89.Ve všech ostatních případech použijte makra v STDARGS.H.

Pokud je zkompilován s použitím /clr (Common Language Runtime), programy, které používají tato makra může způsobit neočekávané výsledky z důvodu rozdílů mezi systémy typu nativní a common language runtime (CLR).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);
    }
}

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 testit očekává, že jeho druhý parametr buď int nebo char*.Předávaných argumentů je 0xffffffff ( unsigned int, ne int) a NULL (skutečně k int, nikoli char*).Když je program zkompilován pro nativní kód, vytvoří tento výstup:

  
  

Však, když je program zkompilován s použitím /clr:pure, neshody typu způsobit tím způsobit výjimku.Řešením je použít explicitní přetypování:

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

Požadavky

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

Zastaralé záhlaví:<varargs.h>

Knihovny

Všechny verze běhových knihoven 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;
}

Výsledek

  

Ekvivalent v rozhraní .NET Framework

Třída System::ParamArrayAttribute

Viz také

Referenční dokumentace

Přístup k argumentu

vfprintf, _vfprintf_l, vfwprintf, _vfwprintf_l