Níže uvedený text pochází z prvního vydání. Nad tímto textem se nachází aktuální stav po revizi směřující k druhému vydání.
O čem si budeme povídat?
Třetím z našich základních stavebních kamenů je větvení nebo také podmíněný příkaz. Jde jednoduše o pojmy, které popisují schopnost provést jednu z několika možných posloupností příkazů (jednu z větví) a to v závislosti na nějaké podmínce.
Dříve, v době assemblerovských programů, bylo větvení realizováno
nejjednodušším možným způsobem — použitím instrukce JUMP.
Program v tomto místě doslova skočil na určenou adresu v paměti. Obvykle to
bylo podmíněno tím, že výsledkem předchozí instrukce byla nula. I když
nebylo možné použít jiný způsob realizace podmíněného příkazu, byly takto
napsány úžasně složité programy. To potvrzovalo správnost Dijkstrových
tvrzení o minimálních požadavcích potřebných pro programování. Když se
objevily vyšší programovací jazyky, objevila se i nová podoba instrukce
JUMP pod názvem GOTO. V jazyku BASIC (i v jiných vyšších
programovacích jazycích) lze GOTO stále používat. Vyzkoušejte si
následující úsek kódu:
10 PRINT "Začínáme na řádku 10" 20 J = 5 30 IF J < 10 GOTO 50 40 Print "Tento řádek se nevytiskne" 50 STOP
Povšimněte si, že dokonce i u tak krátkého programu trvá několik sekund, než přijdete na to co se stane. Kód nemá žádnou strukturu. Musíte si ji během čtení doslova vytvořit. U velkých programů to začne být prakticky nemožné. Z tohoto důvodu moderní programovací jazyky buď nemají příkazy skoku JUMP nebo GOTO, nebo vás od jejich používání odrazují.
Intuitivně nejzřejmější podobou podmíněného příkazu je konstrukce
if, then, else. Sleduje logiku anglické věty v tom smyslu, že
if (jestliže) je nějaká boolovská podmínka splněna, then
(pak) se provede blok příkazů, v opačném případě (nebo else
(jinak)) se provede jiný blok.
V jazyce BASIC se příkaz if používá takto:
PRINT "Začínáme zde"
J = 5
IF J > 10 THEN
PRINT "Toto se nikdy nevytiskne"
ELSE
STOP
END IF
Takový zápis se ve srovnání s předchozím příkazem s GOTO
lépe čte a je srozumitelnější. Za slovo if můžeme samozřejmě
dosadit libovolnou podmínku testu za předpokladu, že ji lze vyhodnotit jako
True nebo False — to znamená jako boolovskou hodnotu.
V jazyce Python vypadá zápis docela podobně:
import sys # jen proto, abychom mohli program ukončit
print "Začínáme zde"
j = 5
if j > 10:
print "Toto se nikdy nevytiskne"
else:
sys.exit()
Vždyť je to téměř shodné, že ano?
Příkazy if/then/else můžete spojovat tím, že vnoříte jeden do druhého — třeba takto:
# Předpokládajme, že sirka již byla dříve vytvořena...
if sirka == 100:
plocha = 0
else:
if sirka == 200:
delka = delka * 2
else:
if sirka == 500:
sirka = sirka / 10
else:
print "Šířka má neočekávanou hodnotu!"
Poznámka: V uvedených příkazech if jsme pro test na
shodnost použili operátor ==, zatímco pro přiřazování hodnot
proměnným jsme použili operátor =. Při programování v jazyce
Python je situace, kdy použijeme = v místě, kde jsme měli
použít ==, jednou z běžných chyb. (Tento problém se týká i jiných jazyků.
Například v jazycích C a C++ se používají stejné operátory.) Python
vás naštěstí varuje, že jde o syntaktickou chybu. Ale někdy se stává, že se
na to musíte podívat pořádně, než příčinu problému zpozorujete.
Možná si ještě vzpomínáte, že jsme se v kapitole o datech zmínili o datovém typu boolean.
Řekli jsme si, že má pouze dvě hodnoty: True a
False. Boolovské proměnné vytváříme velmi zřídka[1], ale dočasné boolovské
hodnoty často vznikají jako výsledek vyhodnocení výrazů. Výrazem
rozumíme kombinaci proměnných a hodnot, spojených operátory s cílem
vyprodukovat výslednou hodnotu. V následujícím příkladu
if x < 5: print x
je zápis x < 5 výrazem. Výrazy mohou být libovolně složité
s tím, že výsledkem jejich vyhodnocení musí být vždy jediná koncová hodnota.
V případě větvení musí být výsledkem pravdivostní hodnota true nebo
false[2]. Nicméně, definice těchto dvou pravdivostních hodnot se jazyk
od jazyka liší. V mnoha jazycích je hodnota false ztotožněna s
hodnotou 0 nebo s hodnotou vyjadřující neexistenci (té se často
říká NULL, Nil nebo None). Takže v
boolovském kontextu bude například prázdný seznam nebo prázdný řetězec
vyhodnocen jako false. To znamená, že například můžeme využít cyklu
while pro zpracování seznamu, které má skončit v okažiku, kdy
je seznam prázdný.
V jazyce Tcl je příkaz if velmi podobný:
if {$x < 5} {
puts $x
}elseif {$x == 5} {
puts "Je to pětka!"
}else{
puts "Hodnota je větší, než pět."
}
Zápis by vám měl být jasný. Části elseif a else
samozřejmě nejsou povinné. Ale to vás již pravděpodobně napadlo.
Posloupnost zanořených if/else/if/else… patří k tak běžným konstrukcím, že některé jazyky poskytují speciální způsob větvení. Konstrukce tohoto typu se často označují jako konstrukce typu Case nebo Switch. V jazyce Tcl ji zapisujeme takto:
switch $sirka {
100 { set plocha 0}
200 { set delka [expr {$delka * 2}] }
500 { set sirka [expr {$sirka / 10}] }
}
V moderních verzích jazyka BASIC tato konstrukce existuje také:
SELECT CASE sirka CASE 100 LET plocha = 0 CASE 200 LET delka = delka * 2 CASE 500 LET sirka = sirka / 10 ELSE PRINT "Šířka má neočekávanou hodnotu!" END SELECT
Python explicitní konstrukci typu case nepodporuje. Místo toho
nabízí kompromis v podobě if/elif/else:
if sirka < 100: plocha = 0 elif sirka < 200: delka = length * 2 elif sirka < 500: sirka = sirka / 10 else: print "Šířka má neočekávanou hodnotu!"
Povšimněte si použití elif a skutečnosti, že se odsazení
(které je v jazyce Python důležité) nemění. Za zmínku stojí i to, že
obě verze — jak tato, tak dříve uvedený příklad v jazyce
Python — jsou funkčně shodné. Druhý způsob pouze zvyšuje čitelnost v
případech, kdy použijeme větší množství testů.
O něco těžkopádnější podobu stejné konstrukce naleznete i v jazyce BASIC
v podobě ElseIf...THEN. Používá se naprosto stejným způsobem,
jako elif v jazyce Python, ale setkáte se s ní zřídka, protože
použití alternativního příkazu CASE je jednodušší.
Až dosud byly naše příklady velmi abstraktní. Podívejme se nyní na příklad, který používá větvení pro něco hmatatelnějšího a který současně představuje další běžnou programovací techniku, konkrétně použití menu pro vymezení uživatelského vstupu.
Zde máme kód, za kterým následuje krátká diskuse. Poznámka překladatele: Abychom se zatím vyhnuli problémům s českými znaky, použijeme texty bez diakritických znamének. Způsob řešení, kdy používáme i české znaky s diakritikou, můžete nalézt v dalších kapitolách.
################################# # Povšimněte si, že pro vytvoření menu bylo použito ztrojených uvozovek. print """ Vyberte si tvar z nasledujiciho seznamu: 1) Trojuhelnik 2) Ctverec 3) Kruh """ tvar = raw_input("Ktery tvar volite? [1, 2, 3] ") # Povšimněte si, že při testování musíme použít řetězec '1' # a ne číslo 1, protože raw_input() vrací řetězce a nikoliv čísla. if tvar == '1': # trojúhelník vyska = input('Jaka je vyska vaseho trojuhelniku? ') zakladna = input('Jaka je delka jeho zakladny? ') print "Plocha trojuhelniku je: ", 0.5 * zakladna * vyska elif tvar == '2': # čtverec strana = input("Jak dlouhe jsou strany strany ctverce? ") print "Plocha ctverce je: ", strana * strana elif tvar == '3': # kruh polomer = input('Jaky je polomer vaseho kruhu? ') print "Plocha kruhu je: ", 3.14159 * polomer * polomer else: print "Lituji. Byla vybrana neplatna volba."
Uživateli tedy předkládáme nabídku voleb. V závislosti na tom, co si
zvolí, požádáme o vstup odpovídajících hodnot a vypočítáme plochu zvoleného
útvaru. Pokud uživatel nevybere jednu z nabídnutých voleb, pak závěrečný
příkaz else jednoduše zobrazí chybové hlášení.
Program tedy uživateli vytváří iluzi, že ví, co uživatel potřebuje. Na základě jeho volby se chová různým způsobem a správně provede odpovídající činnost. Uživateli se v podstatě zdá, že postup řídí, zatímco ve skutečnosti má řízení v rukou programátor, který předvídal, jak mají vypadat všechny platné vstupy a jak má na ně program reagovat. Projevovaná inteligence tedy patří programátorovi, nikoliv stroji. Počítače jsou ve své podstatě hloupé!
Smysl větvení tedy spočívá v tom, že může naše programy vybavit
inteligentním chováním. V závislosti na hodnotách proměnných, které se
vyskytují v podmínkách (ve výše uvedeném případě je to proměnná
tvar), se program ubírá různými cestami uvnitř kódu.
Na závěr byste možná rádi zkusili obalit tento program cyklem, který by způsobil opakované zobrazení menu až do té doby, než by uživatel vybral volbu Konec. Tu byste samozřejmě museli do menu přidat. Pokud se vám to podaří, pak získáte základní šablonu (framework) pro celou řadu programů — zobrazit menu a zachovat se podle výběru uživatele.
Zapamatujte si
if/else.else je nepovinná.if/elif.True nebo
False.Pokud vás napadne, co by se dalo na překladu této kapitoly vylepšit, zašlete e-mail odklepnutím tohoto odkazu. Tím bude do subjektu dopisu automaticky vložena informace o jméně a verzi tohoto HTML dokumentu.
$Id: cztutbranch.html,v 1.2 2004/05/14 10:22:45 prikryl Exp $