6 Příkazy řízení toku Studijní cíl Tento studijní blok má za cíl pokračovat v základních prvcích jazyka Java. Konkrétně bude věnována pozornost příkazům pro řízení toku programu. Pro všechny tyto základní prvky jazyka budou uvedeny příklady. Doba nutná k nastudování 2 2,5 hodiny Příkazy ve zdrojových souborech se obvykle vykonávají odshora dolů v pořadí, ve kterém jsou uvedeny. Příkazy řízení toku však mění pořadí provádění tím, že zavádějí rozhodování, cykly a větvení. 6.1 Podmíněný příkaz Z předchozího studia již znáte různé možnosti pro zápis rozhodování např. formou vývojových diagramů (viz Obrázek 1, Obrázek 2), formou struktogramů nebo pomocí rozhodovacích tabulek. Obrázek 1: Neúplné rozhodování (výv. diagr.) Obrázek 2: Úplné rozhodování (výv. diagr.) Vhodným přístupem pro řešení úloh se složitým rozhodováním jsou rozhodovací tabulky, které jsou nástrojem k vyjádření komplexní logiky rozhodování jednoduchým způsobem. V rozhodovacích tabulkách se znázorňují variantní série činností, které se mají provést při různých kombinacích vstupních podmínek. Základní tvar rozhodovací tabulky je uveden v následující tabulce. KST/IZAPR - Základy programování blok 6, strana 1 (7) Michael Bažant
Název tabulky 1 Seznam podmínek 2 Seznam činností Záhlaví pravidel 3 Kombinace podmínek 4 Kombinace činností Příklad rozsáhlejší rozhodovací tabulky je uveden v další tabulce, která představuje rozhodování pro různé problémy s tiskárnou (část 1 tabulky), dále různé kombinace podmínek (část 3 tabulky), seznam činností pro úkony vedoucí k odstranění problému s tiskárnou (část 2 tabulky) a kombinaci činností, kterou je nutné vykonat pro odstranění problému s tiskárnou (část 4 tabulky). Odstranění závady na tiskárně Pravidla Tiskárna netiskne A A A A N N N N Svítí červená dioda A A N N A A N N Tiskárna nebyla rozeznána OS A N A N A N A N Zkontrolovat napájecí kabel Zkontrolovat datový kabel X X Kontrola instalace ovladače tiskárny X X X X Kontrola/výměna inkoustu X X X X Kontrola uvíznutí papíru X X X 6.1.1 Příkaz if-then V jazyce Java je nejjednodušším ze všech příkazů řízení toku příkaz if-then, kdy se určitá část kódu provede pouze tehdy, když má vyhodnocení příslušného testu hodnotu true. Základní syntaxe tohoto příkazu je následující: if (vyraz) prikaz; V případě použití tohoto základního tvaru by došlo při splnění podmínky ke zpracování pouze jednoho příkazu, i pokud bychom jich chtěli vykonat více. Z tohoto důvodu se vždy doporučuje používat bloky, v nichž se může nacházet libovolný počet příkazů. Doporučuje se tedy používat následující zápis: if (vyraz) { prikaz; } KST/IZAPR - Základy programování blok 6, strana 2 (7) Michael Bažant
Podmínkou pro správný zápis příkazu if-then je, že výraz vždy zapisujeme do závorky a tento výsledkem tohoto výrazu musí být vždy hodnota true nebo false. 6.1.2 Příkaz if-then-else Příkaz if-then-else poskytuje druhou větev provádění, pokud je výsledkem vyhodnocení výrazu hodnota false. Zápis potom vypadá následovně: if (vyraz) { prikaz1; } else { prikaz2; } 6.1.3 Příkaz switch Na rozdíl od předchozích příkazů poskytuje příkaz switch libovolný počet možných větví provádění. Výraz v příkazu switch může být primitivního datového typu char, byte, short, int a potom také vybraných referenčních datových typů (k této problematice se dostaneme v dalších blocích). Zápis příkazu switch je následující: switch (vyraz) { case konst1: blok1; case konst2: blok2; default: blokd; } Konstanty (konst1 a konst2 v příkladu) v návěští case jsou vyhodnoceny v pořadí shora dolů, nelze používat dvě a více návěští se stejnou hodnotou. První konstanta odpovídající výrazu je vstupním bodem a vykonají se všechny zbývající varianty (až na případy, kdy použijeme příkaz break). Pokud hodnotě výrazu neodpovídá žádné návěští, je řízení předáno návěští default. Návěští default může být (nemusí být uvedeno vůbec) v jednom přepínači pouze jedno a nemusí být na konci příkazu switch. Pokud je dosaženo příkazu break (ten je volitelný, ale používá se často), tak se pokračuje dalším příkazem za příkazem switch. Následující příklad demonstruje použití příkazů if-then-else a switch pro vyřešení stejného příkladu. Při porovnání obou příkazů bychom dospěli k následujícím závěrům: ve výrazu příkazu if lze porovnávat hodnoty různých typů KST/IZAPR - Základy programování blok 6, strana 3 (7) Michael Bažant
ve výrazu příkazu switch výhradně uvedené datové typy příkaz if-else-if provede nejvýše jednu z variant příkaz switch může provést více variant po sobě, pokud neuveden příkaz break Obrázek 3: Porovnání příkazu if-then-else a příkazu switch 6.2 Příkazy cyklu Příkazy cyklu používáme v případech, kdy potřebujeme provádět nějakou akci opakovaně. U cyklu rozlišujeme řídící podmínku cyklu a tělo cyklu. Řídící podmínka určuje, zda bude vykonáno tělo cyklu nebo zda dojde k předání řízení za příkaz cyklu. V jazyce Java jsou k dispozici tři základní typy cyklů: while, do-while, a cyklus for a všechny probíhají, dokud je výraz vyhodnocovaný v podmínce cyklu roven hodnotě true. Při výběru typu cyklu záleží na konkrétní situaci a zejména na určení, zda se má tělo cyklu vykonat vždy alespoň jednou a zda známe předem počet opakování. V zásadě je možné uměle cykly zaměňovat (tzn. vystačit si i s jedním typem cyklu), ale je to spíše známka toho, že se nejedná o kvalitního programátora (často u naivního paradigmatu, amatérů apod.). 6.2.1 Příkaz while Tento typ cyklu používáme v případech, kdy je neznámý počet opakování cyklu a cyklus (v závislosti na vyhodnocení podmínky) nemusí proběhnout ani jednou ( viz Obrázek 4). KST/IZAPR - Základy programování blok 6, strana 4 (7) Michael Bažant
Obrázek 4: Syntaxe a vývojový diagram cyklu while Jakékoliv proměnné použité ve výrazu musí být deklarovány před cyklem. Tento typ cyklu je např. vhodný pro čtení ze souboru (může být prázdný, proto nemusí proběhnout ani jednou). Příklady na cyklus while: Obrázek 5: Příklady na cyklus while 6.2.2 Příkaz do-while Tento příkaz je velmi podobný předchozímu cyklu while s tím rozdílem, že podmínka rozhodující o průběhu je na konci celého příkazu (viz Obrázek 6). Tento cyklus rovněž probíhá tak dlouho, dokud platí podmínka a vždy proběhne alespoň jednou. KST/IZAPR - Základy programování blok 6, strana 5 (7) Michael Bažant
Obrázek 6: Syntaxe a vývojový diagram cyklu do-while 6.2.3 Příkaz for Příkaz cyklu for se od předchozích dvou příkazů cyklu liší tím, že příkaz for probíhá po stanovený počet opakování. Deklarace cyklu for se skládá se ze tří částí deklarace + inicializace, výraz typu boolean a iterace, přičemž jednotlivé části jsou odděleny středníkem. Obrázek 7: Syntaxe a vývojový diagram cyklu for Deklarační a inicializační část může obsahovat deklaraci a inicializaci jedné nebo více proměnných stejného typu. Deklarační část proběhne pouze jednou v rámci cyklu (další dvě části probíhají při každém průchodu cyklem) a to hned na začátku. Platnost proměnných deklarovaných v rámci cyklu je omezena pouze na blok cyklu. Výraz typu boolean může obsahovat pouze jeden výraz (nemůže jich být více), nelze tedy testovat více podmínek. KST/IZAPR - Základy programování blok 6, strana 6 (7) Michael Bažant
Iterační výraz je vykonán vždy po vykonání těla příkazu - definujeme v něm, co se má stát při každé iteraci cyklu. Vykonání iteračního výrazu a vyhodnocení podmínky jsou vždy poslední dvě záležitosti, které se odehrají v cyklu for (až na výjimky vztahující se k přerušení cyklu). V iteračním výrazu nemusí vždy docházet k inkrementaci (může se jednat i o dekrementaci) a nemusí být vždy o hodnotu 1. Neúplný příkaz for (např. bez iterační části apod.) lze ze syntaktického hlediska používat, ale nepodporuje to dobrou čitelnost a pochopení zdrojového kódu. V takových případech je v takových případech využít jiný typ cyklu. Od verze jazyka Java 1.5 je k dispozici také zkrácená verze cyklu for, která umožňuje snazší průchod kolekcemi (pole, seznamy apod.). Tato verze cyklu se skládá pouze ze dvou částí deklarační části a výrazu. Syntaxe je následující: for (deklarace : vyraz) Deklarace představuje novou proměnnou kompatibilního typu s prvky pole, která je platná v bloku. Výraz musí představovat kolekci pro procházení (např. pole, seznam atd.). 6.2.4 Příkazy break a continue Příkaz break umožňuje ukončit cyklus v libovolném místě těla cyklu, přičemž se pokračuje se dalším příkazem po ukončeném cyklu. V případě vnořených cyklů ukončí jen nejbližší cyklus. Příkaz continue ukončí aktuální iteraci cyklu a výpočet pokračuje další iterací vynucení nového vyhodnocení podmínky. Otázky na procvičení 1. Kdy se vykonává vyhodnocení podmínky v cyklu se známým počtem opakování? 2. Jaká plátí zásada pro výraz zapsaný v rámci příkazu se známým počtem opakování? 3. Kolikrát proběhne deklarační část v cyklu se známým počtem opakování? 4. Jakého typu může být výraz uvedený ve vícenásobném rozhodování? 5. Jaké jsou možnosti pro zápis podmíněného příkazu v jazyce Java? Odkazy a další studijní prameny 1. Java Tutorial - http://docs.oracle.com/javase/tutorial/ KST/IZAPR - Základy programování blok 6, strana 7 (7) Michael Bažant