Podprogram
Podprogram (anglicky subroutine) je v informatice označení části počítačového programu, kterou je možné opakovaně použít („vyvolat“) v různých místech programu, i z podprogramů. Podprogram může mít parametry, které určují, s jakými daty má pracovat, a může vracet hodnotu použitelnou při jeho vyvolání z výrazu. V některých programovacích jazycích se podprogramy rozlišují na funkce a procedury podle toho, zda vrací hodnotu nebo ne, v mnoha jazycích se pro podprogramy používá jeden z těchto termínů bez rozlišování, zda nějakou hodnotu vracejí. V objektovém programování se podprogramy tříd nazývají metody, v paralelním programování se používají koprogramy, jinde též jako volatelné unity, subprogramy a podobně.[1]
Používání procedur je důležitým nástrojem strukturovaného programování a umožňuje zavádět do programů vyšší míru abstrakce.
Charakteristika
editovatPoužívání podprogramů je při programování natolik mocný nástroj,[2] že jej umožňuje naprostá většina programovacích jazyků. Používání podprogramů může vést ke snížení nákladů na údržbu rozsáhlých projektů a zároveň zvyšovat jejich kvalitu a spolehlivost.[3] Podprogramy jsou často sdružovány do knihoven, které se zaměřují na určitou oblast (například práce s grafikou, zvukem, šifrování a podobně). Knihovny usnadňují sdílení a prodej kódu. Objektově orientované programování přidružilo podprogramy k datům (tj. metody jsou součástí objektů nebo tříd).
Podprogram může mít parametry (také označované za „argumenty“ jako v matematice), tedy při volání zadávané vstupní hodnoty podprogramu, které udávají, s jakými hodnotami má pracovat. Podprogram může vracet návratovou hodnotu.
Motivace
editovatDůvody pro členění programu na podprogramy jsou různé:
- 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ů nebo knihoven
- rozvržení projektu mezi více programátorů
- odstínění detailů implementace od konkrétního použití funkce
Návratová hodnota
editovatNěkteré jazyky, jako Pascal, Fortran, Ada striktně rozlišují dva druhy podprogramů – funkce a 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. Podle toho lze rozlišit dvě hlavní skupiny podprogramů:
- procedura – podprogram, který nevrací výslednou hodnotu a volá se jako příkaz,
- funkce – podprogram, který vrací hodnotu a lze jej volat ve výrazu.
Výsledek a chování programové funkce na rozdíl od funkce v matematice se chová odlišně. To spočívá ve dvou projevech:
- nemusí záviset jen na jeho parametrech a při volání se stejnými parametry může podprogram vracet jiné návratové hodnoty. Důvodem je, že při svém provádění může pracovat i s jinými daty, z jiných zdrojů, než se zadávanými parametry a provádět s nimi vstupní nebo výstupní operace; nejběžnějším příkladem takových vstupů jsou změřené hodnoty nebo čas počítače
- obdobně návratová hodnota zdaleka nemusí být jeho jediným výsledkem, ale má i vedlejší účinek, může měnit i jiné hodnoty, než jen vrácené do výrazu, ve kterém byla funkce volána, například hodnoty ovlivňující vzhled zobrazení.
Parametry podprogramu
editovatPodle 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ů
editovatPodle 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; ve funkci se může tento argument vyhodnocovat vícekrát; používá se ve funkcionálních jazycích a ve skriptovacích jazycích vyžívajících textové nahrazování; v kompilovaných jazycích jde o anachronismus; nejčastější použití je u symbolických maker;
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.
Rekurzivní funkce
editovatFunkci nazveme rekurzivní pokud v jejím těle zavoláme tutéž funkci, tj. funkce volá sama sebe, je zacyklená. 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
editovatPř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.
Ukázky
editovatJazyk C a C++
editovatJazyk 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*);
Jazyk PHP
editovatV netypovaný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.
Odkazy
editovatReference
editovatV tomto článku byl použit překlad textu z článku Subroutine na anglické Wikipedii.
- ↑ U.S. Election Assistance Commission. Definitions of Words with Special Meanings [online]. 2007 [cit. 2013-01-14]. Dostupné v archivu pořízeném dne 2012-12-08.
- ↑ Donald E. Knuth. The Art of Computer Programming, Volume I: Fundamental Algorithms. [s.l.]: Addison-Wesley ISBN 0-201-89683-4.
- ↑ O.-J. Dahl; E. W. DIJKSTRA; C. A. R. HOARE. Structured Programming. [s.l.]: Academic Press, 1972. ISBN 0-12-200550-3.
Související články
editovatExterní odkazy
editovat- Slovníkové heslo funkce ve Wikislovníku