va_arg
, va_copy
, va_end
, va_start
Acessa listas de argumentos variáveis.
Sintaxe
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)
Parâmetros
type
Tipo de argumento a ser recuperado.
arg_ptr
Ponteiro para a lista de argumentos.
dest
Ponteiro para a lista de argumentos a ser inicializada de src
src
Ponteiro para a lista inicializada de argumentos a ser copiada para dest
.
prev_param
Parâmetro que precede o primeiro argumento opcional.
Valor retornado
va_arg
retorna o argumento atual. va_copy
va_end
e va_start
não retornam valores.
Comentários
As macros va_arg
, va_copy
, va_end
e va_start
fornecem uma maneira portátil de acessar os argumentos de uma função quando ela aceita uma quantidade variável de argumentos. Há duas versões das macros: as macros definidas em STDARG.H
estão em conformidade com a norma ISO C99; as macros definidas em VARARGS.H
foram preteridas, mas são mantidas para fins de compatibilidade com versões anteriores de código escrito antes da norma ANSI C89.
Essas macros pressupõem que a função usa um número fixo de argumentos necessários, seguido por um número variável de argumentos opcionais. Os argumentos necessários são declarados como parâmetros comuns para a função e podem ser acessados por meio dos nomes de parâmetro. Os argumentos opcionais são acessados por meio das macros no STDARG.H
(or VARARGS.H
para código escrito antes da norma ANSI C89), que define um ponteiro para o primeiro argumento opcional na lista de argumentos, recupera os argumentos da lista e redefine o ponteiro quando o processamento do argumento é concluído.
As macros do padrão do C, definidas no STDARG.H
, são usadas da seguinte maneira:
va_start
definearg_ptr
como o primeiro argumento opcional na lista de argumentos passada à função. O argumentoarg_ptr
deve ter o tipova_list
. O argumentoprev_param
é o nome do parâmetro necessário imediatamente anterior ao primeiro argumento opcional na lista de argumentos. Seprev_param
for declarado com a classe de armazenamento do registro, comportamento da macro será indefinido.va_start
deve ser usado antes deva_arg
ser usado pela primeira vez.va_arg
recupera um valor detype
do local fornecido porarg_ptr
e incrementaarg_ptr
para apontar o próximo argumento da lista usando o tamanho detype
para determinar o local em que o próximo argumento se inicia.va_arg
pode ser usado várias vezes na função para recuperar argumentos da lista.va_copy
faz uma cópia de uma lista de argumentos em seu estado atual. O parâmetrosrc
já deve estar inicializado comva_start
; ele pode ter sido atualizado com chamadasva_arg
, mas não pode ter sido redefinido comva_end
. O próximo argumento recuperado porva_arg
dedest
é o mesmo que o próximo argumento recuperado desrc
.Após a recuperação de todos os argumentos,
va_end
redefine o ponteiro comoNULL
.va_end
deve ser chamado em cada lista de argumentos inicializada comva_start
ouva_copy
antes de retornar a função.
Observação
As macros em VARARGS.H foram preteridas e são mantidas somente para compatibilidade com versões anteriores do código gravado antes da norma ANSI C89 com. Em outros casos, use as macros em STDARGS.H.
Quando eles são compilados usando /clr
(Common Language Runtime Compilation), os programas que usam essas macros podem gerar resultados inesperados devido a diferenças entre sistemas de tipo CLR (Common Language Runtime) nativos e comuns. 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);
}
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*
}
Observe que testit
espera que seu segundo parâmetro seja 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 o programa é compilado para código nativo, ele produz esta saída:
-1
(null)
Requisitos
Cabeçalho: <stdio.h>
e <stdarg.h>
Cabeçalho obsoleto: <varargs.h>
Bibliotecas
Todas as versões das bibliotecas em tempo de execução C.
Exemplo
// 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
Confira também
Acesso ao argumento
vfprintf
, _vfprintf_l
, vfwprintf
, _vfwprintf_l