Funkce s proměnným počtem parametrů

Princip funkcí s proměnným počtem parametrů (dále FPPP) je založen na skutečnosti, že při každém volání funkce jsou hodnoty skutečných parametrů kopírovány na zásobník (paměť používaná pro uložení lokálních proměných a parametrů funkcí). Pokud tedy známe adresu a typ (velikost paměti potřebnou k jeho uložení) některého parametru, můžeme přistoupit také k následujícímu parametru. FPPP tedy:

  • musí mít vždy alespoň jeden pevný parametr a
  • musí být určeno, kolik parametrů v paměti následuje (je znám počet nebo je použita nějaká zarážka)
  • a jaké jsou datové typy těchto parametrů.

Typické příklady FPPP

  • funkce, u níž počet parametrů a jejich typy jsou dány předaným formátovacím textovým řetězcem (např. printf)
  • funkce, u kterých se předpokládá se určitý typ parametrů a předá se jejich počet (např. suma, průměr čísel)
  • funkce, u kterých se předpokládá určitý typ parametrů a konec seznamu parametrů je označen zarážkou - domluvenou hodnotou (např. spojení textových řetězců)

Deklarace FPPP

Při deklaraci (definici) FPPP se používá tzv. výpustka (…), která následuje po povinných parametrech funkce. Příklady deklarace funkce:

double prumer(int pocet, double prvni, ...);
int print(char* format, ...);

Volání FPPP

Příklad volání funkce:

double prum;
 
prum = prumer(5, 1.2, 2.3, 4.3, 2.5, 7.1);
print("Průměr je %g. \n", prum);

Zpracování parametrů v těle funkce

Díky makrům z knihovny stdarg.h nemusíme znát přesnou strukturu zásobníku (je implementačně závislá) a práce s FPPP je tak relativně jednoduchá. V stdarg.h je definován typ va_list, který používáme pro uložení adresy parametrů v zásobníku, a 3 makra va_start(), va_arg() a va_end().

Při psaní těla FPPP je nejprve nutné deklarovat si alespoň jednu proměnnou typu va_list a tuto proměnnou nastavit na první z “volitelných” parametrů pomocí makra va_start(), jehož argumenty by měly být identifikátor nastavované proměnné typu va_list a identifikátor posledního “pevného” parametru. Příklad:

va_list parametry;
va_start(parametry, posledni_pevny);

Jednotlivé parametry pak získáváme prostřednictvím makra va_arg(), jehož argumenty jsou ukazatel na zásobník a očekávaný datový typ dalšího parametru. Vyhodnocení makra va_arg() má za následek také posunutí ukazatele na zásobník. Příklad:

cislo = va_arg(parametry, double);

Pokud jsme získali všechny “volitelné” parametry, je potřeba ukončit práci s ukazatelem na zásobník pomocí makra va_end(). Příklad:

va_end(parametry);

Příklad FPPP

double prumer(int pocet, double prvni, ...){
   double out;
   va_list param;
   int i;
 
   out = prvni;
   va_start(param, prvni);
 
   i = pocet - 1;
   while (i > 0) {
      out += va_arg(param, double);
      i--;
   }
 
   va_end(param);
   out = out / pocet;
 
   return out;
}

Praxe

  • c99 potřebuje ještě va_copy() ??? viz 3/stdarg

—- cc,upol

jazykc/funkce-s-promennym-poctem-parametru.txt · Last modified: 2015/01/15 20:47 (external edit)
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0