va_arg, va_copy, va_end, va_startva_arg, va_copy, va_end, va_start

Accède à des listes d’arguments variables.Accesses variable-argument lists.

SyntaxeSyntax

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)

ParamètresParameters

typetype
Type d’argument à récupérer.Type of argument to be retrieved.

arg_ptrarg_ptr
Pointeur désignant la liste d’arguments.Pointer to the list of arguments.

destdest
Pointeur vers la liste d’arguments à initialiser à partir de srcPointer to the list of arguments to be initialized from src

srcsrc
Pointeur vers la liste d’arguments initialisée à copier vers dest.Pointer to the initialized list of arguments to copy to dest.

prev_paramprev_param
Paramètre qui précède le premier argument facultatif.Parameter that precedes the first optional argument.

Valeur de retourReturn Value

va_arg retourne l’argument actuel.va_arg returns the current argument. va_copy, va_start et va_end ne retournent pas de valeurs.va_copy, va_start and va_end do not return values.

NotesRemarks

Les macros va_arg, va_copy, va_endet va_start offrent un moyen portable d’accéder aux arguments d’une fonction lorsque la fonction accepte un nombre variable d’arguments.The va_arg, va_copy, va_end, and va_start macros provide a portable way to access the arguments to a function when the function takes a variable number of arguments. Il existe deux versions des macros : Macros définies dans STDARG. H conforme à la norme ISO C99 ; macros définies dans VARARGS. H sont dépréciées, mais sont conservées pour la compatibilité descendante avec le code qui a été écrit avant la norme ANSI C89.There are two versions of the macros: The macros defined in STDARG.H conform to the ISO C99 standard; the macros defined in VARARGS.H are deprecated but are retained for backward compatibility with code that was written before the ANSI C89 standard.

Ces macros considèrent que la fonction accepte un nombre fixe d’arguments obligatoires, suivi d’un nombre variable d’arguments facultatifs.These macros assume that the function takes a fixed number of required arguments, followed by a variable number of optional arguments. Les arguments obligatoires sont déclarés à la fonction en tant que paramètres ordinaires et sont accessibles via les noms des paramètres.The required arguments are declared as ordinary parameters to the function and can be accessed through the parameter names. Les arguments facultatifs sont accessibles via les macros contenues dans STDARG.H (ou dans VARARGS.H pour le code qui a été écrit avant la norme ANSI C89). Ils définissent le pointeur désignant le premier argument facultatif de la liste d’arguments, récupère les arguments de la liste et réinitialise le pointeur dès que le traitement de l’argument est terminé.The optional arguments are accessed through the macros in STDARG.H (or VARARGS.H for code that was written before the ANSI C89 standard), which sets a pointer to the first optional argument in the argument list, retrieves arguments from the list, and resets the pointer when argument processing is completed.

Les macros standard C, définies dans STDARG.H, sont utilisées comme suit :The C standard macros, defined in STDARG.H, are used as follows:

  • va_start définit arg_ptr sur le premier argument facultatif de la liste d’arguments passée à la fonction.va_start sets arg_ptr to the first optional argument in the list of arguments that's passed to the function. L’argument arg_ptr doit avoir le type va_list .The argument arg_ptr must have the va_list type. L’argument prev_param est le nom du paramètre requis qui précède immédiatement le premier argument facultatif dans la liste d’arguments.The argument prev_param is the name of the required parameter that immediately precedes the first optional argument in the argument list. Si prev_param est déclaré avec la classe de stockage Register, le comportement de la macro n’est pas défini.If prev_param is declared with the register storage class, the macro's behavior is undefined. va_start doit être utilisé avant que va_arg soit utilisé pour la première fois.va_start must be used before va_arg is used for the first time.

  • va_arg récupère une valeur de type à partir de l’emplacement donné par arg_ptr, et incrémente arg_ptr pour pointer vers l’argument suivant dans la liste en utilisant la taille du type pour déterminer l’emplacement où commence l’argument suivant.va_arg retrieves a value of type from the location that's given by arg_ptr, and increments arg_ptr to point to the next argument in the list by using the size of type to determine where the next argument starts. va_arg peut être utilisé un nombre quelconque de fois dans la fonction pour récupérer des arguments de la liste.va_arg can be used any number of times in the function to retrieve arguments from the list.

  • va_copy effectue une copie d’une liste d’arguments dans son état actuel.va_copy makes a copy of a list of arguments in its current state. Le paramètre src doit déjà être initialisé avec va_start; elle a peut-être été mise à jour avec des appels va_arg , mais elle ne doit pas avoir été réinitialisée avec va_end.The src parameter must already be initialized with va_start; it may have been updated with va_arg calls, but must not have been reset with va_end. L’argument suivant récupéré par va_arg à partir de dest est le même que l’argument suivant extrait de src.The next argument that's retrieved by va_arg from dest is the same as the next argument that's retrieved from src.

  • Une fois tous les arguments récupérés, va_end réinitialise le pointeur à la valeur null.After all arguments have been retrieved, va_end resets the pointer to NULL. va_end doit être appelé sur chaque liste d’arguments initialisée avec va_start ou va_copy avant le retour de la fonction.va_end must be called on each argument list that's initialized with va_start or va_copy before the function returns.

Notes

Les macros contenues dans VARARGS.H sont obsolètes et sont conservées uniquement pour assurer une compatibilité descendante avec le code qui a été écrit avant la norme ANSI C89.The macros in VARARGS.H are deprecated and are retained only for backwards compatibility with code that was written before the ANSI C89 standard. Dans tous les autres cas, utilisez les macros contenues dans STDARGS.H.In all other cases, use the macros in STDARGS.H.

Quand ils sont compilés à l’aide de /clr (compilation pour le Common Language Runtime), les programmes qui utilisent ces macros peuvent générer des résultats inattendus en raison des différences entre les systèmes de type natif et les systèmes de type CLR (Common Language Runtime).When they are compiled by using /clr (Common Language Runtime Compilation), programs that use these macros may generate unexpected results because of differences between native and common language runtime (CLR) type systems. Prenons l’exemple de ce programme :Consider this 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*
}

Notez que testit s’attend à ce que le deuxième paramètre soit un entier ou un caractère*.Notice that testit expects its second parameter to be either an int or a char*. Les arguments passés sont 0xFFFFFFFF (un intnon signé , et non un int) et null (en fait un entier, et non un caractère*).The arguments being passed are 0xffffffff (an unsigned int, not an int) and NULL (actually an int, not a char*). Quand le programme est compilé pour du code natif, il génère cette sortie :When the program is compiled for native code, it produces this output:

-1

(null)

Configuration requiseRequirements

En-tête : <stdio.h> et <stdarg.h>Header: <stdio.h> and <stdarg.h>

En-tête obsolète : <varargs.h>Deprecated Header: <varargs.h>

BibliothèquesLibraries

Toutes les versions des bibliothèques Runtime C.All versions of the C run-time libraries.

ExempleExample

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

Voir aussiSee also

Accès à un argumentArgument Access
vfprintf, _vfprintf_l, vfwprintf, _vfwprintf_lvfprintf, _vfprintf_l, vfwprintf, _vfwprintf_l