va_arg
, , va_copy
, , va_end
va_start
Uzyskuje dostęp do list zmiennych-argumentów.
Składnia
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)
Parametry
type
Typ argumentu do pobrania.
arg_ptr
Wskaźnik do listy argumentów.
dest
Wskaźnik do listy argumentów do zainicjowania z src
src
Wskaźnik do zainicjowanej listy argumentów, aby skopiować do dest
elementu .
prev_param
Parametr poprzedzający pierwszy opcjonalny argument.
Wartość zwracana
va_arg
Zwraca bieżący argument. va_copy
va_start
i va_end
nie zwracają wartości.
Uwagi
Makra va_arg
, va_copy
, va_end
i va_start
zapewniają przenośny sposób uzyskiwania dostępu do argumentów do funkcji, gdy funkcja przyjmuje zmienną liczbę argumentów. Istnieją dwie wersje makr: makra zdefiniowane zgodnie STDARG.H
ze standardem ISO C99; makra zdefiniowane w VARARGS.H
pliku są przestarzałe, ale są zachowywane w celu zachowania zgodności z poprzednim kodem, który został napisany przed standardem ANSI C89.
Te makra zakładają, że funkcja przyjmuje stałą liczbę wymaganych argumentów, a następnie zmienną liczbę argumentów opcjonalnych. Wymagane argumenty są deklarowane jako zwykłe parametry funkcji i mogą być dostępne za pośrednictwem nazw parametrów. Opcjonalne argumenty są dostępne za pośrednictwem makr w STDARG.H
pliku (lub VARARGS.H
dla kodu, który został napisany przed standardem ANSI C89), który ustawia wskaźnik na pierwszy opcjonalny argument na liście argumentów, pobiera argumenty z listy i resetuje wskaźnik po zakończeniu przetwarzania argumentów.
Standardowe makra języka C zdefiniowane w STDARG.H
systemie są używane w następujący sposób:
va_start
ustawiaarg_ptr
na pierwszy opcjonalny argument na liście argumentów przekazywanych do funkcji. Argumentarg_ptr
musi miećva_list
typ . Argumentprev_param
jest nazwą wymaganego parametru, który bezpośrednio poprzedza pierwszy opcjonalny argument na liście argumentów. Jeśliprev_param
zostanie zadeklarowana z klasą rejestru magazynu, zachowanie makra jest niezdefiniowane.va_start
należy użyć przedva_arg
pierwszym zastosowaniem.va_arg
Pobiera wartośćtype
z lokalizacji podanej przezarg_ptr
parametr i zwiększaarg_ptr
, aby wskazać następny argument na liście przy użyciu rozmiarutype
, aby określić, gdzie rozpoczyna się następny argument.va_arg
Można użyć dowolnej liczby razy w funkcji, aby pobrać argumenty z listy.va_copy
Tworzy kopię listy argumentów w bieżącym stanie. Parametrsrc
musi być już zainicjowany za pomocąva_start
polecenia . Być może został zaktualizowany za pomocąva_arg
wywołań, ale nie może zostać zresetowany za pomocą poleceniava_end
. Następny argument pobrany przezva_arg
dest
program jest taki sam jak następny argument pobrany z elementusrc
.Po pobraniu
va_end
wszystkich argumentów zresetuj wskaźnik naNULL
.va_end
Musi być wywoływana na każdej liście argumentów zainicjowanej za pomocąva_start
funkcji lubva_copy
przed zwróceniem funkcji.
Uwaga
Makra w usłudze VARARGS. H są przestarzałe i są zachowywane tylko w celu zapewnienia zgodności z poprzednimi wersjami kodu, który został napisany przed standardem ANSI C89. We wszystkich innych przypadkach użyj makr w pliku STDARGS.H.
Gdy są one kompilowane przy użyciu /clr
(kompilacja środowiska uruchomieniowego języka wspólnego), programy korzystające z tych makr mogą generować nieoczekiwane wyniki z powodu różnic między systemami typów środowiska uruchomieniowego natywnego i wspólnego języka (CLR). Rozważmy ten program:
#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*
}
Zwróć uwagę, że testit
jego drugi parametr ma być parametrem int
char*
lub . Przekazywane argumenty są 0xffffffff (a unsigned int
, a nie int
) i NULL
(faktycznie int
, a nie char*
). Gdy program jest kompilowany dla kodu natywnego, generuje następujące dane wyjściowe:
-1
(null)
Wymagania
Nagłówek: <stdio.h>
i <stdarg.h>
Przestarzały nagłówek: <varargs.h>
Biblioteki
Wszystkie wersje bibliotek czasu wykonywania języka C.
Przykład
// 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
Zobacz też
Dostęp do argumentów
vfprintf
, , _vfprintf_l
, , vfwprintf
_vfwprintf_l