7. seminář - Funkce s proměnným počtem parametrů

TEACHINGZPC2

Dosud jsme definovali jen funkce s pevným počtem parametrů. Používali jsme ale i funkce které měli proměnlivý počet parametrů a to funkci printf, které jsme předávali formátovací řetězec a libovolný počet argumenů.

Víme že hodnoty parametrů funkcí se ukladají na zásobník. Tyto hodnoty jsou v paměti tedy uloženy za sebou. Pokud tedy známe adresu a velikost datového typu jsme schopni se přesunout na další parametr.

Funkce s proměnným počtem parametrů musí mít alespoň jeden pevný parametr a musí být zadán počet parametrů které následují. Prvním způsobem jak toho docilít je předat počet ja pevný parametr a nebo použít zarážku. Poslední informací jsou datové typ těchto parametrů. Tyto informace můžeme předat následovně:

  • Počet argumentů a jejich typy předány formátovacím řetězcem (např. printf).
  • Předpokládáme typ parametrů a funkci je předán jejich počet (např. suma, průměr).
  • předpokládáme typ parametrů a máme určenou zarážku (např. práce s řetězci).

Deklarace

Pro delklaraci proměnného počtu parametrů používáme ...


    int sum(size_t count, ...) {
        // Implementace funkce
    }
    
    int a = sum(4, 8, 9, 14, 57);
    
    // V jazyce C NEMUZEME sum definovat nasledovne
    int sum(...) { /* Implementace funkce */ }

Zpracování parametrů v těle funkce

V knihovně stdarg.h jsou definována makra pro práci s parametry: va_list, va_start, va_arg, va_end kde:

  • va_list je datový typ pro uložení odkazu na parametry.
  • va_start inicializuje proměnnou va_list.
  • va_arg čte další parametr.
  • va_end ukončuje práci s parametry.

Příklad použití


    #include <stdio .h> 
    #include <stdarg.h>
    
    double average(int count, ...) {
        // V tele funkce musime deklarovat alespon 
        // jednu promennou typu va_list
        va_list parameters;
        
        // Nastavime parameters na prvni nepovinny parametr
        va_start(parameters, count);
        double sum = 0;
        
        for(int i = 0; i < count; i += 1) {
            // Ziskame hodnotu nepovinneho parametru
            sum = sum + va_arg(parameters, double);
        }
        
        // Ukoncime praci s parametry
        va_end(parameters);
        return sum / count;
    }
    
    int main() {
        printf ("%f \n" , average(5 , 1.2 , 3.4 , 5.6 , 7.8 , 9.0));
        return 0; 
    }


Úkoly

Napište funkci, která vrací nejmenší z předaných celočíselných parametrů. Funkce bere jako první argument počet předaných celých čísel.
Napište funkci Complex sum(size_t count, ...), která vypočítá součet předaných komplexních čísel. Počet sčítaných čísel je určen pevným parametrem count, za nímž pak ve volání funkce následují hodnoty, které mé funkce sčítat. Pro práci s komplexními čísly je nutné vytvořit strukturovaný datový typ Complex.