IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 5 - Podmínky (větvení) v Dartu

V předešlém cvičení, Řešené úlohy k 4. lekci Dartu, jsme si procvičili nabyté zkušenosti z předchozích lekcí.

V minulé lekci Dart kurzu, Řešené úlohy k 4. lekci Dartu, jsme si podrobně probrali datové typy. Abychom si něco naprogramovali, potřebujeme nějak reagovat na různé situace. Může to být například hodnota zadaná uživatelem, podle které budeme chtít měnit další běh programu. Říkáme, že se program větví a k větvení používáme podmínky, těm se budeme věnovat celý dnešní tutoriál. Vytvoříme program na výpočet odmocniny a vylepšíme naši kalkulačku.

Podmínky

V Dartu se podmínky píší úplně stejně, jako ve všech C-like jazycích, pro začátečníky samozřejmě vysvětlím. Pokročilejší se asi budou chvilku nudit. :-)

Podmínky zapisujeme pomocí klíčového slova if, za kterým následuje logický výraz. Pokud je výraz pravdivý, provede se následující příkaz. Pokud ne, následující příkaz se přeskočí a pokračuje se až pod ním. Vyzkoušejme si to:

if (15 > 5)
    print('Pravda');
print('Program zde pokračuje dál');

Výstup programu:

Konzolová aplikace
Pravda
Program zde pokračuje dál

Pokud podmínka platí (což zde ano), provede se příkaz vypisující do konzole text pravda. V obou případech program pokračuje dál. Součástí výrazu samozřejmě může být i proměnná:

print('Zadej nějaké číslo');
int a = int.parse(stdin.readLineSync(encoding: UTF8));
if (a > 5)
    print('Zadal jsi číslo větší než 5!');
print('Děkuji za zadání');

Ukažme si nyní relační operátory, které můžeme ve výrazech používat:

Operátor C-like zápis
Rovnost ==
Je ostře větší >
Je ostře menší <
Je větší nebo rovno >=
Je menší nebo rovno <=
Nerovnost !=
Obecná negace !

Rovnost zapisujeme dvěma == proto, aby se to nepletlo s běžným přiřazením do proměnné, které se dělá jen jedním =. Pokud chceme nějaký výraz znegovat, napíšeme ho do závorky a dáme před něj vykřičník. Když budeme chtít vykonat více než jen jeden příkaz, musíme příkazy vložit do bloku ze složených závorek:

print('Zadej nějaké číslo');
int a = int.parse(stdin.readLineSync(encoding: UTF8));
if (a > 0) {
    print('Zadal jsi číslo větší než 0, to znamená, že ho mohu odmocnit!');
    double o = sqrt(a);
    print('Odmocnina z čísla $a je $o');
}
print('Děkuji za zadání');

Výstup programu:

Konzolová aplikace
Zadej nějaké číslo
144
Zadal jsi číslo větší než 0, to znamená, že ho mohu odmocnit!
Odmocnina z čísla 144 je 12.0
Děkuji za zadání

Program načte od uživatele číslo a pokud je větší než 0, vypočítá z něj druhou odmocninu. Mimo jiné jsme použili knihovnu dart:math, která obsahuje řadu užitečných matematických metod. Na konci této kapitoly si ji blíže představíme. Metoda sqrt() vrací hodnotu jako double. Bylo by hezké, kdyby nám program vyhuboval v případě, že zadáme záporné číslo. S dosavadními znalostmi bychom napsali něco jako:

print('Zadej nějaké číslo, ze kterého spočítám odmocninu:');
int a = int.parse(stdin.readLineSync(encoding: UTF8));
if (a > 0) {
    print('Zadal jsi číslo větší než 0, to znamená, že ho mohu odmocnit!');
    double o = sqrt(a);
    print('Odmocnina z čísla $a je $o');
}
if (a <= 0) print('Odmocnina ze záporného čísla neexistuje!');
print('Děkuji za zadání');

Všimněte si, že musíme pokrýt i případ, kdy se a == 0, nejen když je menší. Kód však můžeme výrazně zjednodušit pomocí klíčového slova else, které vykoná následující příkaz nebo blok příkazů v případě, že se podmínka neprovede:

print('Zadej nějaké číslo, ze kterého spočítám odmocninu:');
int a = int.parse(stdin.readLineSync(encoding: UTF8));
if (a > 0) {
    print('Zadal jsi číslo větší než 0, to znamená, že ho mohu odmocnit!');
    double o = sqrt(a);
    print('Odmocnina z čísla $a je $o');
} else
    print('Odmocnina ze záporného čísla neexistuje!');
print('Děkuji za zadání');

Kód je mnohem přehlednější a nemusíme vymýšlet opačnou podmínku, což by v případě složené podmínky mohlo být někdy i velmi obtížné. V případě více příkazů by byl za else doplnil opět blok { }.

Else se také využívá v případě, kdy potřebujeme v příkazu manipulovat s proměnnou z podmínky a nemůžeme se na ni tedy ptát potom znovu. Program si sám pamatuje, že se podmínka nesplnila a přejde do sekce else. Ukažme si to na příkladu: Mějme číslo a, kde bude hodnota 0 nebo 1 a po nás se bude chtít, abychom hodnotu prohodili (pokud tam je 0, dáme tam 1, pokud 1, dáme tam 0). Naivně bychom mohli kód napsat takto:

int a = 0; // do a si přiřadíme na začátku 0

if (a == 0) // pokud je a 0, dáme do něj jedničku
    a = 1;
if (a == 1) // pokud je a 1, dáme do něj nulu
    a = 0;

print(a);

Nefunguje to, že? Pojďme si projet, co bude program dělat. Na začátku máme v a nulu, první podmínka se jistě splní a dosadí do a jedničku. No ale rázem se splní i ta druhá. Co s tím? Když podmínky otočíme, budeme mít ten samý problém s jedničkou. Jak z toho ven? Ano, použijeme else.

int a = 0; // do a si přiřadíme na začátku 0

if (a == 0) // pokud je a 0, dáme do něj jedničku
    a = 1;
else // pokud je a 1, dáme do něj nulu
    a = 0;

print(a);

Podmínky je možné skládat a to pomocí dvou základních logických operátorů:

Operátor C-like zápis
A zároveň &&
Nebo ||

Uveďme si příklad:

print('Zadejte číslo v rozmezí 10-20:');
int a = int.parse(stdin.readLineSync(encoding: UTF8));
if ((a >= 10) && (a <= 20))
    print('Zadal jsi správně');
else
    print('Zadal jsi špatně');

S tím si zatím vystačíme, operátory se pomocí závorek samozřejmě dají kombinovat.

print('Zadejte číslo v rozmezí 10-20 nebo 30-40:');
int a = int.parse(stdin.readLineSync(encoding: UTF8));
if (((a >= 10) && (a <= 20)) || ((a >= 30) && (a <= 40)))
    print('Zadal jsi správně');
else
    print('Zadal jsi špatně');

Switch

Switch je konstrukce, převzatá z jazyka C (jako většina gramatiky Dartu). Umožňuje nám zjednodušit (relativně) zápis více podmínek pod sebou. Vzpomeňme si na naši kalkulačku v prvních lekcích, která načetla 2 čísla a vypočítala všechny 4 operace. Nyní si ale budeme chtít zvolit, kterou operaci chceme. Bez switche bychom napsali kód podobný tomuto:

print('Vítejte v kalkulačce');
print('Zadejte první číslo:');
double a = double.parse(stdin.readLineSync(encoding: UTF8));
print('Zadejte druhé číslo:');
double b = double.parse(stdin.readLineSync(encoding: UTF8));
print('Zvolte si operaci:');
print('1 - sčítání');
print('2 - odčítání');
print('3 - násobení');
print('4 - dělení');
int volba = int.parse(stdin.readLineSync(encoding: UTF8));
double vysledek;
if (volba == 1)
    vysledek = a + b;
else if (volba == 2)
    vysledek = a - b;
else if (volba == 3)
    vysledek = a * b;
else if (volba == 4)
    vysledek = a / b;
if ((volba > 0) && (volba < 5))
    print('Výsledek: $vysledek');
else
    print('Neplatná volba');
print('Děkuji za použití kalkulačky.');

Výstup aplikace:

Konzolová aplikace
Vítejte v kalkulačce
Zadejte první číslo:
3.14
Zadejte druhé číslo:
2
Zvolte si operaci:
1 - sčítání
2 - odčítání
3 - násobení
4 - dělení
3
Výsledek: 6.28
Děkuji za použití kalkulačky.

Všimněte si, že v kódu máme vychytávku pro kontrolu správnosti volby. Program by v tomto případě fungoval stejně i bez těch else, ale nač se dále ptát, když již máme výsledek.

Nyní si zkusíme napsat ten samý kód pomocí switche:

print('Vítejte v kalkulačce');
print('Zadejte první číslo:');
double a = double.parse(stdin.readLineSync(encoding: UTF8));
print('Zadejte druhé číslo:');
double b = double.parse(stdin.readLineSync(encoding: UTF8));
print('Zvolte si operaci:');
print('1 - sčítání');
print('2 - odčítání');
print('3 - násobení');
print('4 - dělení');
int volba = int.parse(stdin.readLineSync(encoding: UTF8));
double vysledek;
switch (volba) {
    case 1:
        vysledek = a + b;
        break;
    case 2:
        vysledek = a - b;
        break;
    case 3:
        vysledek = a * b;
        break;
    case 4:
        vysledek = a / b;
        break;
}
if ((volba > 0) && (volba < 5))
    print('Výsledek: $vysledek');
else
    print('Neplatná volba');
print('Děkuji za použití kalkulačky.');

Vidíme, že kód je trochu přehlednější. Pokud bychom potřebovali v nějaké větvi switche spustit více příkazů, překvapivě je nebudeme psát do {} bloku, ale rovnou pod sebe. Blok {} nám zde nahrazuje příkaz break, který způsobí vyskočení z celého switche. Switch může místo case x: obsahovat ještě možnost default:, která se vykoná v případě, že nebude platit žádný case. Je jen na vás, jestli budete switch používat, obecně se vyplatí jen při větším množství příkazů a vždy jde nahradit sekvencí if a else. Nezapomínejte na breaky. Switch jde samozřejmě udělat i pro hodnoty stringové proměnné.

To bychom měli. V příští lekci, Řešené úlohy k 5. lekci Dartu, nás čekají pole a cykly, tím dovršíme základní znalosti, máte se na co těšit. :)

V následujícím cvičení, Řešené úlohy k 5. lekci Dartu, si procvičíme nabyté zkušenosti z předchozích lekcí.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 6x (2.88 kB)
Aplikace je včetně zdrojových kódů v jazyce Dart

 

Předchozí článek
Řešené úlohy k 4. lekci Dartu
Všechny články v sekci
Základní konstrukce jazyka Dart
Přeskočit článek
(nedoporučujeme)
Řešené úlohy k 5. lekci Dartu
Článek pro vás napsal Honza Bittner
Avatar
Uživatelské hodnocení:
5 hlasů
FIT ČVUT alumnus :-) Sleduj mě na https://twitter.com/tenhobi a ptej se na cokoli na https://github.com/tenhobi/ama.
Aktivity