V programování se funkce s proměnným počtem argumentů nazývají variadické.
Existuje mnoho matematických a logických operací, které se nejlépe implementují pomocí funkcí s proměnným počtem argumentů, jako je sčítání čísel nebo zřetězení řetězců.
Chcete-li implementovat funkce s proměnným počtem argumentů v programovacím jazyce C, musíte zahrnout hlavičkový soubor stdarg.h. Dříve používaný varargs.h, jehož podpora byla ukončena. Pro C++ se tento hlavičkový soubor nazývá cstdarg[1] .
#include <stdarg.h> dvojitý průměr ( int count , ...) { va_list ap ; int j ; dvojitý součet = 0 ; va_start ( ap , počet ); /* Vyžaduje poslední známý argument (pro získání adresy prvního neznámého) */ for ( j = 0 ; j < počet ; j ++ ) { součet += va_arg ( ap , double ); /* Zvyšuje ap na další argument. */ } va_end ( ap ); vrátit součet / počet ; }Tato funkce umožňuje vypočítat průměrnou hodnotu z libovolného počtu argumentů. Všimněte si, že funkce nezná počet argumentů a jejich typy. Funkce z výše uvedeného příkladu očekává, že typy budou doublea že počet parametrů je předán v prvním argumentu. V jiných případech, jako například u funkce printf() , se počet a typy argumentů odvozují z formátovacího řetězce.
Obecně byste si měli být vědomi výchozího pravidla povýšení typu, které uvádí, že jsou povýšeny všechny argumenty funkcí, včetně neznámých argumentů. Pokud by tedy ve výše uvedeném příkladu byly neznámé argumenty deklarovány typu float, byly by ve skutečnosti typu doublea funkce by očekávala typ double, nikoli float. To může způsobit zmatek a chyby, pokud funkce očekává argument určité dimenze, ale obdrží argument jiné dimenze. Použití makra NULLv variadic funkcích je obzvláště nebezpečné, protože NULLv C je definováno specifickou implementací a nemusí být přetypováno na typ null void *a v C++ je definováno jako 0 bez explicitní konverze na ukazatel. Číslo 0 je typu int, které má minimální velikost 16 bitů (2 bajty), což pravděpodobně není velikost ukazatele očekávaného ve funkci.
stdarg.h deklaruje typ va_lista definuje čtyři funkce maker : va_start , va_arga va_copy .va_end