Partager via


va_arg ; va_end ; va_start

Listes d'accès argument variable.

type va_arg(
   va_list arg_ptr,
   type 
);
void va_end(
   va_list arg_ptr 
);
void va_start(
   va_list arg_ptr,
   prev_param 
); // (ANSI version)
void va_start(
   arg_ptr 
);  // (Pre-ANSI-standardization version)

Paramètres

  • type
    Type d'argument doivent être récupérées.

  • arg_ptr
    Pointeur vers la liste d'arguments.

  • prev_param
    Paramètre précédant le premier argument facultatif (ANSI uniquement).

Valeur de retour

va_argRenvoie l'argument actuel ; va_startet va_end ne retournent pas de valeurs.

Notes

Le va_arg, va_end, et va_start les macros fournissent un moyen portable pour accéder aux arguments à une fonction lorsque la fonction accepte un nombre variable d'arguments.Deux versions des macros sont disponibles : les macros définies dans STDARG.H sont conformes à la norme ANSI C.Les macros définies dans les VARARGS.H sont obsolète et rester pour des raisons de compatibilité descendante.Ils ont été conçus pour une utilisation avant la normalisation ANSI.

Ces macros supposent que la fonction accepte un nombre fixe d'arguments requis, suivie d'un nombre variable d'arguments facultatifs.Les arguments requis sont déclarés en tant que paramètres ordinaires à la fonction et est accessible via les noms de paramètre.Les arguments facultatifs sont accessibles via les macros dans STDARG.H ou VARARGS.H, définie un pointeur vers le premier argument facultatif dans la liste d'arguments, extraire les arguments de la liste et redéfinir le pointeur lorsque le traitement de l'argument est terminée.

C ANSI standard macros, définies dans STDARG.H, sont utilisés comme suit :

  • va_startdéfinit arg_ptr pour le premier argument facultatif dans la liste d'arguments passés à la fonction.L'argument arg_ptr doit avoir 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.Si prev_param est déclarée avec la classe de stockage Registre, comportement de la macro n'est pas défini.va_startdoit être utilisée avant va_arg est utilisé pour la première fois.

  • va_argRécupère une valeur de type à partir de l'emplacement donné par arg_ptr et s'incrémente arg_ptr pour pointer vers l'argument suivant dans la liste, à l'aide de la taille de type pour déterminer où commence l'argument suivant.va_argpeut être utilisé n'importe quel nombre de fois au sein de la fonction pour extraire les arguments de la liste.

  • Une fois que tous les arguments ont été récupérées, va_end réinitialise le pointeur pour NULL.

Remarque pour C++Remarque pour C++

Les macros définies dans les VARARGS.H sont désapprouvées et existent exclusivement pour des raisons de compatibilité vers l'arrière.Utilisez les macros définies dans STDARGS.H, sauf si vous travaillez avec du code avant de la norme ANSI.

Lorsqu'il est compilé avec /clr (Compilation pour le Common Language Runtime), les programmes utilisant ces macros peuvent générer des résultats inattendus en raison des différences entre les systèmes de types natifs et common language runtime.Pensez à ce programme :

#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*
}

Notez que testit attend son deuxième paramètre soit une int ou un char*.Les arguments transmis sont 0xffffffff (une unsigned int, pas un int) et NULL (en fait une int, et non pas un char*).Lorsqu'il est compilé pour le code natif, le programme génère la sortie

-1
(null)

Toutefois, lorsqu'il est compilé avec /clr:pure, les incompatibilités de types causer le programme génère une exception.La solution consiste à utiliser des casts explicites :

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

Configuration requise

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

Ancien en-tête : <varargs.h>

Bibliothèques

Toutes les versions de la C run-time libraries.

Exemple

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

#include <stdio.h>
#include <stdarg.h>
int average( int first, ... );

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

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

   /* Call with just -1 terminator. */
   printf( "Average is: %d\n", average( -1 ) );
}

/* Returns the average of a variable list of integers. */
int average( int first, ... )
{
   int count = 0, sum = 0, i = first;
   va_list marker;

   va_start( marker, first );     /* Initialize variable arguments. */
   while( i != -1 )
   {
      sum += i;
      count++;
      i = va_arg( marker, int);
   }
   va_end( marker );              /* Reset variable arguments.      */
   return( sum ? (sum / count) : 0 );
}

Sortie

Average is: 3
Average is: 8
Average is: 0

Équivalent .NET Framework

Classe System::ParamArrayAttribute

Voir aussi

Référence

Argument Access

vfprintf, _vfprintf_l, vfwprintf, _vfwprintf_l