va_arg, va_end, va_start
Listas de argumentos de variable de acceso.
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 que desea recuperar.arg_ptr
Puntero a la lista de argumentos.prev_param
Parámetro precede al primer argumento opcional (sólo en ANSI).
Valor devuelto
va_argDevuelve el argumento actual; va_starty va_end no devuelven valores.
Comentarios
El va_arg, va_end, y va_start las macros proporcionan un medio portátil para tener acceso a los argumentos a una función cuando la función toma un número variable de argumentos.Existen dos versiones de las macros: las macros definidas en STDARG.H se ajustan al estándar ANSI C.Las macros definidas en VARARGS.H están obsoleto y permanecen para compatibilidad con versiones anteriores.Fueron diseñados para su uso antes de estandarización de ANSI.
Estas macros se supone que la función toma un número fijo de argumentos requeridos, seguido por un número variable de argumentos opcionales.Los argumentos necesarios se declaran como parámetros normales a la función y pueden accederse a través de los nombres de parámetro.Los argumentos opcionales se acceden a través de las macros en STDARG.H o VARARGS.H, que establece un puntero al primer argumento opcional en la lista de argumentos, recuperar argumentos de la lista y restablecer el puntero del mouse cuando se completa el procesamiento de argumentos.
Las macros estándar de ANSI C, definidas en STDARG.H, se utilizan como sigue:
va_startestablece arg_ptr al primer argumento opcional de la lista de argumentos pasados a la función.El argumento arg_ptr debe tener va_list tipo.El argumento prev_param es el nombre del parámetro requerido inmediatamente antes del primer argumento opcional en la lista de argumentos.Si prev_param se declara con la clase de almacenamiento de información de registro, comportamiento de la macro no está definido.va_startse debe utilizar antes de va_arg se utiliza por primera vez.
va_argRecupera un valor de type desde la ubicación proporcionada por arg_ptr y los incrementos arg_ptr para que señale al siguiente argumento en la lista, utilizando el tamaño de type para determinar dónde comienza el siguiente argumento.va_argse puede utilizar cualquier número de veces dentro de la función para recuperar argumentos de la lista.
Después de recuperar todos los argumentos, va_end restablece el puntero a NULL.
Nota para C++ |
---|
Las macros definidas en VARARGS.H están en desuso y existe exclusivamente para compatibilidad con versiones anteriores.Utilizar las macros definidas en STDARGS.H a menos que trabaje con código antes de la norma ANSI. |
Cuando se compila con /clr (Compilación de Common Language Runtime), programas que utilizan estas macros pueden generar resultados inesperados debido a diferencias entre sistemas de tipos en tiempo de ejecución de lenguaje nativo y común.Tenga en cuenta 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*
}
Tenga en cuenta que testit espera su segundo parámetro puede ser un int o un char*.Los argumentos que se pasan son 0xffffffff (una unsigned int, no un int) y NULL (en realidad un int, no un char*).Cuando se compila a código nativo, el programa produce la salida
-1
(null)
Sin embargo, cuando se compila con /clr:pure, los errores de coincidencia de tipo que el programa generar una excepción.La solución consiste en utilizar conversiones explícitas:
int main()
{
testit( 0, (int)0xFFFFFFFF ); // cast unsigned to int
testit( 1, (char*)NULL ); // cast int to char*
}
Requisitos
Encabezado: <stdio.h> y <stdarg.h>
Encabezado antiguo: <varargs.h>
Bibliotecas
Todas las versiones de la bibliotecas en tiempo de ejecución de c.
Ejemplo
// 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 );
}
Output
Average is: 3
Average is: 8
Average is: 0
Equivalente en .NET Framework
Clase System::ParamArrayAttribute