va_arg
, , va_copy
va_end
va_start
Greift auf Variablenargumentelisten zu.
Syntax
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)
Parameter
type
Typ des abzurufenden Arguments.
arg_ptr
Zeiger auf die Liste der Argumente.
dest
Zeiger auf die Liste von Argumenten, die von src
initialisiert werden
src
Zeiger auf die initialisierte Liste von Argumenten, die von dest
kopiert werden.
prev_param
Parameter, der dem ersten optionalen Argument vorausgeht.
Rückgabewert
va_arg
gibt das aktuelle Argument zurück. va_copy
va_start
und va_end
geben keine Werte zurück.
Hinweise
Die Makros va_arg
, va_copy
, va_end
und va_start
ermöglichen auf portierbare Weise, auf die Argumente für eine Funktion zuzugreifen, wenn die Funktion eine variable Anzahl von Argumenten akzeptiert. Es gibt zwei Versionen der Makros: Die makros, die gemäß STDARG.H
dem ISO C99-Standard definiert sind. Die definierten VARARGS.H
Makros sind veraltet, werden jedoch aus Gründen der Abwärtskompatibilität mit Code beibehalten, der vor dem ANSI C89-Standard geschrieben wurde.
Diese Makros setzen voraus, dass die Funktion eine feste Anzahl von erforderlichen Argumenten akzeptiert, gefolgt von einer variablen Anzahl von optionalen Argumenten. Die erforderlichen Argumente werden als gewöhnliche Parameter für die Funktion deklariert und können über die Parameternamen aufgerufen werden. Auf die optionalen Argumente wird über die Makros in STDARG.H
(oder VARARGS.H
für Code zugegriffen, der vor dem ANSI C89-Standard geschrieben wurde), der einen Zeiger auf das erste optionale Argument in der Argumentliste festlegt, Argumente aus der Liste abruft und den Zeiger zurücksetzt, wenn die Argumentverarbeitung abgeschlossen ist.
Die in STDARG.H
C definierten Standardmakros werden wie folgt verwendet:
va_start
legtarg_ptr
auf das erste optionale Argument in der Liste der Argumente fest, die an die Funktion übergeben wird. Das Argumentarg_ptr
muss über den Typva_list
verfügen. Das Argumentprev_param
ist der Name des erforderlichen Parameters, der dem ersten optionalen Argument in der Argumentliste direkt vorausgeht. Wennprev_param
mit der Registerspeicherklasse deklariert wird, ist das Verhalten des Makros undefiniert.va_start
muss verwendet werden, bevorva_arg
zum ersten Mal verwendet wird.va_arg
ruft einentype
-Wert vom Speicherort ab, der vonarg_ptr
angegeben wird, und inkrementiertarg_ptr
, um auf das folgende Argument in der Liste zu verweisen, indem mithilfe der Größe vontype
bestimmt wird, wo das folgende Argument beginnt.va_arg
kann in der Funktion beliebig oft verwendet werden, um Argumente aus der Liste abzurufen.va_copy
erstellt eine Kopie von einer Argumentliste im aktuellen Zustand. Dersrc
-Parameter muss bereits mitva_start
initialisiert sein. Er kann mithilfe vonva_arg
-Aufrufen aktualisiert worden sein, doch darf er nicht mitva_end
zurückgesetzt worden sein. Das folgende Argument, das vonva_arg
ausdest
abgerufen wird, entspricht dem folgenden Argument, das vonsrc
abgerufen wird.Nachdem alle Argumente abgerufen wurden,
va_end
setzt der Zeiger aufNULL
.va_end
muss in jeder mitva_start
oderva_copy
initialisierten Argumentliste aufgerufen werden, bevor die Funktion Daten zurückgibt.
Hinweis
Die in VARARGS.H definierten Makros sind als veraltet markiert und werden nur beibehalten, weil sie für Code abwärts kompatibel sind, der vor dem ANSI-Standard C89 geschrieben wurde. Verwenden Sie in allen anderen Fällen die Makros in STDARGS.H.
Wenn sie mithilfe /clr
der Kompilierung (Common Language Runtime Compilation) kompiliert werden, generieren Programme, die diese Makros verwenden, möglicherweise unerwartete Ergebnisse aufgrund von Unterschieden zwischen systemeigenen und common language runtime (CLR)-Typsystemen. Beachten Sie dieses Programm:
#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*
}
Berücksichtigen Sie, dass testit
als zweiten Parameter entweder int
oder char*
voraussetzt. Die übergebenen Argumente sind 0xffffffff ( unsigned int
, aber nicht int
) und NULL
(tatsächlich ein int
, aber kein char*
). Wenn das Programm für nativen Code kompiliert wird, erzeugt es diese Ausgabe:
-1
(null)
Anforderungen
Kopfzeile: <stdio.h>
und <stdarg.h>
Veraltete Kopfzeile: <varargs.h>
Libraries
Alle Versionen der C-Laufzeitbibliotheken.
Beispiel
// 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
Siehe auch
Argumentzugriff
vfprintf
, , _vfprintf_l
vfwprintf
_vfwprintf_l