Podprogram

Z Wikipedie, otevřené encyklopedie
Skočit na: Navigace, Hledání

Podprogram (anglicky subroutine) je v programování část programu, kterou je možné volat opakovaně z různých míst kódu. Může mít parametry, které udávají, s jakými hodnotami má pracovat, a může vracet návratovou hodnotu. Podprogram, který nevrací hodnotu, se volá jako příkaz; podprogram, který vrací hodnotu, lze vyvolat ve výrazu.

Některé jazyky (Pascal, Fortran, Ada) striktně rozlišují podprogramy, které vracejí hodnotu, a nazývají je funkce, od podprogramů, které návratovou hodnotu nemají, a které nazývají procedury. Jiné jazyky (C, Lisp) takto striktně různé druhy podprogramů nerozlišují a používají buď jen jeden z uvedených názvů nebo je pokládají za synonyma. V objektově orientovaných jazycích se podprogramy náležející určité třídě zpravidla nazývají metody. V mnoha moderních programovacích jazycích se termín podprogram vůbec nepoužívá.

Výsledek a chování podprogramu na rozdíl od funkce v matematice nemusí záviset jen na jeho parametrech. To se projevuje dvěma způsoby. Při volání se stejnými parametry může podprogram vracet jiné hodnoty. Dále podprogram při svém v provádění může pracovat i s jinými daty a provádět vstupní nebo výstupní operace, takže návratová hodnota zdaleka nemusí být jeho jediným výsledkem (viz vedlejší účinek).

Motivace[editovat | editovat zdroj]

  • rozklad složitých problémů na jednodušší, nebo v případě rekurze menší
  • odstranění opakování kódu v programu, a díky parametrům jeho zobecnění
  • umožňuje znovupoužití v jiných programech, obvykle formou modulů nebi knihoven
  • rozvržení projektu mezi více programátorů
  • odstínění detailů implementace od konkrétního použití funkce

Parametry podprogramu[editovat | editovat zdroj]

Související informace naleznete také v článku Parametr funkce.

Podle toho, jestli se parametry vyskytují v definici nebo volání podprogramu, rozlišujeme:

  • formální parametry - jsou parametry použité v definici podprogramu; umožňují specifikovat, jakého datového typu jsou jednotlivé parametry podprogramu, a jaké operace se s nimi uvnitř podprogramu provádějí
  • skutečné parametry (argumenty) - jsou to parametry (výrazy nebo proměnné) použité ve volání funkce; některé programovací jazyky dovolují funkce s proměnným počtem parametrů

Skutečné parametry se zpracují (viz dále) a přiřadí nebo navážou na formální parametry, se kterými pracuje tělo podprogramu.

Předávání parametrů[editovat | editovat zdroj]

Podle vztahu formálního a skutečného parametru rozlišujeme různé metody předávání (neboli volání) parametrů:

volání hodnotou (call by value)
volající provede vyhodnocení výrazu zadaného jako argument funkce a výslednou hodnotu předá příslušnému formálnímu parametru
volání odkazem (call by reference)
volající předá v argumentu funkce ukazatel nebo referenci na proměnou; funkce může obsah této proměnné nejen číst, ale i modifikovat (viz vedlejší účinek)
volání výsledkem (call by result)
při vstupu do funkce má proměnná odpovídající formálnímu parametru nedefinovanou hodnotu; funkce ji může používat jako lokální proměnnou; při skončení funkce se její hodnota předá skutečnému parametru
volání hodnotou a výsledkem (call by value and result)
formální parametr se chová jako lokální proměnná, které se při vstupu do funkce předá hodnota argumentu funkce a při výstupu se předá hodnota zpátky; chování je velmi podobné jako u volání odkazem; rozdíl se projeví, pokud funkce s proměnnou, která se používá jako skutečný parametr, pracuje i přímo
volání jménem (call by name)
výraz v argumentu funkce se nevyhodnocuje a předá se do funkce tak jak je; proto se ve funkci může tento argument vyhodnocovat vícekrát; v kompilovaných jazycích jde o anachronismus; nejčastější použití je u symbolických maker; používá se ve funkcionálních jazycích

Většina programovacích jazyků má jenom část z uvedených metod volání parametrů (nejčastěji volání hodnotou plus jednu z metod volání odkazem, volání hodnotou a výsledkem a volání jménem). V definici funkce se uvádí, jaký způsob volání se má použít pro každý parametr. U některých typů lze vybrat jen některé metody, například pole se obvykle předává odkazem.

Ukázky v programovacích jazycích C a C++[editovat | editovat zdroj]

Jazyk C všechny podprogramy nazývá funkce. Pro vyjádření, že funkce nevrací žádnou hodnotu a nemá žádné parametry se používá klíčové slovo void:

void funkce1(void) { /* nějaký kód */ }

Tato funkce nevrací hodnotu a je volána: funkce1();

int funkce2(void)
  { return 5; }

Tato funkce navrací hodnotu (číslo 5) a funkci můžeme zavolat jako část příkazu: x + funkce2()

char funkce3 (int cislo)
  { char rada[] = {'P','U','S','C','P','S','N'};
    return rada[cislo];
  }

Tato funkce konvertuje číslo mezi 0 a 6 na počáteční písmeno dne v týdnu. Ukázka: 0 → 'P', 1 → 'U', …, 6 → 'N'. Výsledek volání funkce může být přiřazen proměnné:

char pismeno_dne = funkce3(cislo);.

void funkce4 (int* ukazatel_na_promennou)
  { (*ukazatel_na_promennou)++; }

Tato funkce nevrací žádnou hodnotu, ale modifikuje proměnnou, jejíž adresa je zadána v parametru funkce. Funkci lze volat: funkce4(&promenna);.

int (*funkce5(double (*F)(long b), int (*f)(void* c))) (void * v);

Tento řádek deklaruje funkci funkce5 (bez těla, jedná se o predeklaraci), která vrací ukazatel na funkci vracející integer a mající parametr typu nespecifikovaný ukazatel a má dva parametry: první je ukazatel na funkci vracející double (reálné číslo s dvojitou přesností) s parametrem typu long („dlouhé“ celé číslo), druhý je opět ukazatel na funkci, a to stejného typu jako funkce vracená, tedy vracející integer a mající parametr typu nespecifikovaný ukazatel.

Podobné zápisy se v běžných programech vyskytují zřídka, protože bývají zpřehledněny pomocí typedef. Mohou se ale vyskytnout v chybové hlášce překladače nebo v automaticky generovaném zdrojovém kódu. Ekvivalentní definice pomocí typedef zní:

typedef double F1(long);
typedef int F2(void *);
F2 * funkce5(F1*,F2*);

Ukázka v PHP[editovat | editovat zdroj]

V beztypových programovacích jazycích jako PHP je zápis funkce jednodušší: neuvádí se typy argumentů, jen názvy:

function funkce1($a,$b) {
  return($b['num']-$a['num']);
}

Funkce předpokládá, že oba její argumenty jsou asociativní pole obsahující prvek num a vrátí rozdíl těchto prvků. Podobné funkce se často používají jako callback pro řazení, tedy předají se jako argument řadící funkci a ta je opakovaně volá na dvojice prvků řazeného pole.

Rekurzivní funkce[editovat | editovat zdroj]

Podrobnější informace naleznete v článku Rekurzivní funkce (programování).

Funkci nazveme rekurzivní pokud v jejím těle zavoláme tutéž funkci, tj. funkce volá sama sebe. Rekurzivní funkce se v programování používá ke zjednodušení složitějších algoritmů. Nesprávné užití rekurze může způsobit velkou spotřebu paměti a velkou spotřebu času procesoru. Příkladem použití rekurzivní funkce může být algoritmus výpočtu faktoriálu.

Přetížení funkce[editovat | editovat zdroj]

Podrobnější informace naleznete v článku Přetížení funkce.

Přetížení funkce (anglicky overloading) znamená deklarovat více funkcí pod stejným názvem lišících se ve struktuře seznamu parametrů (počet, datový typ). Při volání funkce překladač analyzuje parametry a podle toho určí odpovídající funkci. Přetížení se týká i návratové hodnoty, překladač analyzuje typ požadované návratové hodnoty na levé straně přiřazovacího operátoru = a podle toho vybere příslušnou funkci.

Odkazy[editovat | editovat zdroj]

Reference[editovat | editovat zdroj]

V tomto článku byl použit překlad textu z článku Subroutine na anglické Wikipedii.

Související články[editovat | editovat zdroj]