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