B-PROG2 K tvorbe funkcií

K tvorbe funkcií


Zoberme si jednoduchý príklad: Vytvorte funkciu, ktorá nájde najväčšiu hodnotu v poli.

Naivné riešenie


Naivné riešenie, ktoré je zdanlivo správne:

Všimnite si, čo reálne robí funkcia (a porovnajte si s tým, čo robiť mala):

  1. vyhradí miesto na 10 čísel v poli a 2 premenné;
  2. načíta si 10 čísel;
  3. vypočíta z týchto 10 čísel maximum;
  4. vypíše maximum.

Navyše, pole je tam úplne zbytočné, stačilo napísať:

Takisto je zbytočné použiť funkciu, keď už to píšeme takto, mohli sme tento kód rovno napísať ako súčasť main funkcie.

Evolúcia správneho riešenia


Aby bola funkcia užitočná, musí umožňovať nejakú konkrétnu činnosť pre voliteľné vhodné vstupy (tzv. parametre) a/alebo produkovať určité výstupy.

Pripomeňmne si zadanie: Vytvorte funkciu, ktorá nájde najväčšiu hodnotu v poli.

  1. Funkcia má realizovať nejakú činnosť v závislosti na hodnotách v poli, t.j. celé pole je parameter. Keďže je to parameter, musíme predpokladať, že volajúca funkcia (ktorá využije nami napísanú funkciu) si už nejaké hodnoty načítala, alebo nejako inak získala!
  2. Činnosť funkcie je nájsť najväčšiu hodnotu.
  3. Nie je presne špecifikované, čo má s najväčšou hodnotou spraviť. Nie je však ani napísané, že ju má vypísať. Najrozumnejšie je preto považovať nájdenú hodnotu za výsledok, t.j. výstup z funkcie. Funkcia teda nájdenú hodnotu má vrátiť (v C-čku pomocou kľúčového slova return, a volajúca funkcia sa už rozhodne, čo s tou hodnotou urobí.

Po zvážení horeuvedených bodov môžeme kód prepísať napr. nasledovne:

Ak chceme napr. použiť rovnakým spôsobom ako predtým (načítať, vyrátať maximum, vypísať), napíšeme zvyšný kód do volajúcej funkcie (napr. ak sa to hodí aj do main):

Predstavte si, že chceme napísať program, ktorý zistí, či najväčšie číslo z 10 hodov kockou je 6. Potom stačí prepísať main funkciu nasledovne:

Funkciu maximum môžeme použiť bezo zmeny (kým v naivnom riešení by sme museli funkciu prerábať, resp. vyrobiť novú).

V Príklade 3 som použil v zozname parametrov funkcie int pole[10]. Tým som ale obmedzil funkciu na prácu iba s 10-prvkovými poľami. Čo keď chceme maximum z menej prvkov ako je velkost poľa?

V jazyku C sa polia odovzdávajú do funkcií odkazom na prvú pozíciu v poli. Pre funkciu, ktorá takýto odkaz dostane to hovorí, že od daného miesta v pamäti nasledujú zaradom čísla (ak je to pole int-ov), ale nehovorí koľko tých čísel je. Aby sa to funkcia dozvedela, pridáme 1 parameter, ktorým volajúca funkcia povie, koľko čísel v poli sa má spracovať (všimnite si vynechanie veľkosti poľa v deklarácii parametra):

Pozn.: Ak pracujeme s reťazcami, veľkosť reťazca parameter byť nemusí. Prečo?

Pred funkciu som napísal do komentára predpoklad (PRE:). Ak hodnota parametra nespĺňa predpoklad, funkcia nemusí pracovať správne. Je na volajúcej funkcii (programátorovi, ktorý ju píše), aby zabezpečil dodržanie predpokladov.

Teraz už vieme napísať aj program, ktorý zistí maximum v 2 poloviciach poľa:

Niečo naviac


Funkcia maximum predstavuje určitú šablónu, s ktorou sa dá ďalej pracovať. Napr. môžeme chcieť nie maximum z čísel, ale najdlhší reťazec v poli reťazcov:

Upravil som typy prvkov v poli, a keďže ma zaujímala dĺžka reťazca, doplnil som strlen. Použitie je podobné ako predtým:

Bez toho, aby som menil niečo v main funkcii, viem funkciu max_strlen mierne zrýchliť jej dodatočnou úpravou:

Doplnením pomocných premenných len a maxlen sa nemusí vždy nanovo prepočítavať dĺžka doteraz najväčšieho reťazca (funkcia si ju pamätá).

Analytická úloha


Skúste zistiť sami (bez kompilovania, ako keby ste boli na skúške), čo robí funkcia _cotorobi_, čo je tiež len modifikácia príkladu s maximom: