va_arg
, va_copy
, , va_end
va_start
Přistupuje k seznamům argumentů proměnných.
Syntaxe
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, který se má načíst.
arg_ptr
Ukazatel na seznam argumentů
dest
Ukazatel na seznam argumentů, ze které se mají inicializovat src
src
Ukazatel na inicializovaný seznam argumentů pro zkopírování do dest
.
prev_param
Parametr, který předchází prvnímu volitelnému argumentu.
Vrácená hodnota
va_arg
vrátí aktuální argument. va_copy
va_start
a va_end
nevrací hodnoty.
Poznámky
Makra va_arg
a , va_end
va_copy
va_start
poskytují přenosný způsob, jak získat přístup k argumentům funkce, když funkce přebírá proměnlivý počet argumentů. Existují dvě verze maker: Makra definovaná standardem STDARG.H
ISO C99 jsou zastaralá, VARARGS.H
ale zachovají se kvůli zpětné kompatibilitě s kódem napsaným před standardem ANSI C89.
Tato makra předpokládají, že funkce přebírá pevný počet povinných argumentů následovaných proměnným počtem volitelných argumentů. Požadované argumenty jsou deklarovány jako běžné parametry funkce a lze k němu přistupovat prostřednictvím názvů parametrů. Volitelné argumenty jsou přístupné prostřednictvím maker v STDARG.H
makrech (nebo VARARGS.H
pro kód napsaný před standardem ANSI C89), který nastaví ukazatel na první volitelný argument v seznamu argumentů, načte argumenty ze seznamu a resetuje ukazatel při dokončení zpracování argumentu.
Standardní makra jazyka C definovaná v STDARG.H
:
va_start
nastavíarg_ptr
první volitelný argument v seznamu argumentů předaných funkci.arg_ptr
Argument musí mítva_list
typ.prev_param
Argument je název požadovaného parametru, který bezprostředně předchází prvnímu volitelnému argumentu v seznamu argumentů. Pokudprev_param
je deklarována pomocí třídy úložiště registru, chování makra není definováno.va_start
musí být použit dříve, nežva_arg
se použije poprvé.va_arg
načte hodnotutype
z umístění, které je dáno parametremarg_ptr
, a navýšíarg_ptr
odkaz na další argument v seznamu pomocí velikostitype
určující, kde začíná další argument.va_arg
funkci lze použít libovolný početkrát k načtení argumentů ze seznamu.va_copy
vytvoří kopii seznamu argumentů v aktuálním stavu. Parametrsrc
již musí být inicializovánva_start
pomocí ; mohl být aktualizován volánímva_arg
, ale nesmí být resetován pomocíva_end
. Další argument, který je načten zva_arg
dest
, je stejný jako další argument načtený zsrc
.Po načtení
va_end
všech argumentů obnoví ukazatel naNULL
hodnotu .va_end
musí být volána v každém seznamu argumentů, který je inicializován sva_start
funkcí nebova_copy
před vrácením funkce.
Poznámka:
Makra v nástroji VARARGS. H jsou zastaralé a uchovávají se pouze kvůli zpětné kompatibilitě s kódem napsaným před standardem ANSI C89. Ve všech ostatních případech použijte makra ve SDARGS.H.
Při kompilaci pomocí /clr
(Common Language Runtime Compilation) můžou programy, které používají tato makra, generovat neočekávané výsledky kvůli rozdílům mezi systémy typů CLR (Native And Common Language Runtime). Zvažte tento 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*
}
Všimněte si, že očekává, že testit
jeho druhý parametr bude buď an, int
nebo a char*
. Předané argumenty jsou 0xffffffff (an unsigned int
, nikoli int
) a NULL
(ve skutečnosti , int
nikoli ).char*
Když je program zkompilován pro nativní kód, vytvoří tento výstup:
-1
(null)
Požadavky
Záhlaví: <stdio.h>
a <stdarg.h>
Zastaralá hlavička: <varargs.h>
Knihovny
Všechny verze knihoven runtime jazyka C.
Příklad
// 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
Viz také
Přístup k argumentům
vfprintf
, _vfprintf_l
, , vfwprintf
_vfwprintf_l