va_arg, va_end, va_start

Listas de argumentos de variável de acesso.

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)

Parâmetros

  • type
    Tipo de argumento a ser recuperado.

  • arg_ptr
    Ponteiro para a lista de argumentos.

  • prev_param
    Parâmetro anterior primeiro argumento opcional (somente ANSI).

Valor de retorno

va_argRetorna o argumento atual; va_starte va_end não retornam valores.

Comentários

O va_arg, va_end, e va_start as macros oferecem uma forma portátil para acessar argumentos de uma função quando a função usa um número variável de argumentos.Estão disponíveis duas versões de macros: as macros definidas no STDARG.H em conformidade com o padrão ANSI C.Macros definidas no VARARGS.H são obsoleto e permanecem para compatibilidade com versões anteriores.Eles foram projetados para uso antes da padronização ANSI.

Essas macros pressupõem que a função utiliza um número fixo de argumentos necessários, seguido por um número variável de argumentos opcionais.Argumentos necessários são declarados como parâmetros comuns para a função e podem ser acessados por meio de nomes de parâmetro.Os argumentos opcionais são acessados através de macros em STDARG.H ou VARARGS.H, que definir um ponteiro para o primeiro argumento opcional na lista de argumentos, recuperar os argumentos da lista e redefinir o ponteiro ao argumento processamento está concluído.

Macros padrão da ANSI C, definidas em STDARG.H, são usados como segue:

  • va_startdefine arg_ptr para o primeiro argumento opcional na lista de argumentos passados para a função.O argumento arg_ptr deve ter va_list tipo.O argumento prev_param é o nome do parâmetro necessário imediatamente antes do primeiro argumento opcional na lista de argumentos.Se prev_param é declarada com a classe de armazenamento do registro, comportamento da macro é indefinido.va_startdeve ser usado antes de va_arg é usado pela primeira vez.

  • va_argrecupera um valor de type da localização fornecida pelo arg_ptr e incrementos arg_ptr para apontar para o argumento seguinte na lista, usando o tamanho de type para determinar onde começa o próximo argumento.va_argpode ser usado qualquer número de vezes dentro da função para recuperar os argumentos da lista.

  • Depois de recuperar todos os argumentos, va_end redefine o ponteiro para Nulo.

Anotação de C++Anotação de C++

Macros definidas no VARARGS.H são preteridos e existe apenas para compatibilidade com versões anteriores.Use as macros definidas no STDARGS.H a menos que você estiver trabalhando com código antes do padrão ANSI.

Quando compilado com /CLR (common Language Runtime Compilation), programas usando essas macros podem gerar resultados inesperados devido a diferenças entre sistemas de tipo nativo e do common language runtime.Considere este programa:

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

Observe que testit espera seu segundo parâmetro para ser um int ou char*.Os argumentos passados são 0xffffffff (um unsigned int, e não um int) e NULL (na verdade um int, e não um char*).Quando compilado para código nativo, o programa produz a saída

-1
(null)

No entanto, quando compilado com /clr:pure, incompatibilidades de tipos com que o programa gerar uma exceção.A solução é usar conversões explícitas:

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

Requisitos

Cabeçalho: <stdio.h> e <stdarg.h>

Cabeçalho antigo: <varargs.h>

Bibliotecas

Todas as versões do bibliotecas de tempo de execução c.

Exemplo

// 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 );
}

Saída

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

Equivalência do .NET Framework

Classe System::ParamArrayAttribute

Consulte também

Referência

Argumento Access

vfprintf, _vfprintf_l, vfwprintf, _vfwprintf_l