va_arg
, va_copy
, , va_end
, va_start
Obtiene acceso a listas de argumentos de variable.
Sintaxis
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 que se va a recuperar.
arg_ptr
Puntero a la lista de argumentos.
dest
Puntero a la lista de argumentos que se van a inicializar desde src
src
Puntero a la lista de argumentos inicializada que se va a copiar en dest
.
prev_param
Parámetro que precede al primer argumento opcional.
Valor devuelto
va_arg
devuelve el argumento actual. va_copy
y va_start
va_end
no devuelven valores.
Comentarios
Las macros va_arg
, va_copy
, va_end
y va_start
proporcionan una manera portable de obtener acceso a los argumentos de una función cuando la función toma un número variable de argumentos. Hay dos versiones de las macros. las macros definidas en STDARG.H
cumplen el estándar ISO C99. Las definidas en VARARGS.H
están en desuso, pero se conservan por razones de compatibilidad con el código escrito antes del estándar ANSI C89.
Estas macros suponen que la función toma un número fijo de argumentos necesarios, seguido por un número variable de argumentos opcionales. Los argumentos necesarios se declaran como parámetros ordinarios de la función; se puede obtener acceso a ellos con los nombres de parámetro. El acceso a los argumentos opcionales se realiza mediante las macros de STDARG.H
(o VARARGS.H
para el código escrito antes del estándar ANSI C89), que establece un puntero al primer argumento opcional de la lista de argumentos, recupera argumentos de la lista y restablece el puntero cuando finaliza el procesamiento de argumentos.
Las macros estándar de C, definidas en STDARG.H
, se usan de la manera siguiente:
va_start
establecearg_ptr
en el primer argumento opcional de la lista de argumentos que se pasa a la función. El argumentoarg_ptr
debe tener el tipova_list
. El argumentoprev_param
es el nombre del parámetro necesario inmediatamente anterior al primer argumento opcional de la lista de argumentos. Siprev_param
se declara con la clase de almacenamiento de registro, el comportamiento de la macro es indefinido. Es necesario usarva_start
antes de usarva_arg
por primera vez.va_arg
recupera un valor detype
de la ubicación determinada porarg_ptr
, y aumentaarg_ptr
para señalar al argumento siguiente de la lista usando el tamaño detype
para determinar donde empieza el argumento siguiente.va_arg
se puede usar un número ilimitado de veces en la función para recuperar argumentos de la lista.va_copy
realiza una copia de una lista de argumentos en su estado actual. El parámetro desrc
debe estar ya inicializado conva_start
; puede haberse actualizado con llamadas deva_arg
, pero no puede haberse restablecido conva_end
. El siguiente argumento recuperado porva_arg
dedest
es el mismo que el siguiente argumento se recupera desrc
.Después de que todos los argumentos se hayan recuperado,
va_end
restablece el puntero aNULL
. Es necesario llamar ava_end
en cada lista de argumentos que se inicialice conva_start
ova_copy
antes de que la función devuelva su resultado.
Nota:
Las macros de VARARGS.H han dejado de usarse y se conservan solo por compatibilidad con el código escrito antes de la existencia del estándar ANSI C89. En todos los demás casos, se deben usar las macros de STDARGS.H.
Cuando se compilan mediante /clr
(Compilación de Common Language Runtime), los programas que usan estas macros pueden generar resultados inesperados debido a las diferencias entre los sistemas de tipos nativos y de Common Language Runtime (CLR). Observe 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*
}
testit
espera que su segundo parámetro sea un valor int
o char*
. Los argumentos que se pasan son 0xffffffff (un valor unsigned int
, no un valor int
) y NULL
(en realidad, un valor int
, no un valor char*
). Cuando el programa se compila para código nativo, genera este resultado:
-1
(null)
Requisitos
Encabezado: <stdio.h>
y <stdarg.h>
Encabezado en desuso: <varargs.h>
Bibliotecas
Todas las versiones de las bibliotecas en tiempo de ejecución de C.
Ejemplo
// 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
Vea también
Acceso a argumentos
vfprintf
, _vfprintf_l
, , vfwprintf
, _vfwprintf_l