C# týden ITnetwork summer 2020
30 % bodů zdarma na online výuku díky naší Slevové akci!
Pouze tento týden sleva až 80 % na e-learning týkající se C#

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

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

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í díl. Vytvoříme program na výpočet odmocniny a vylepšíme naši kalkulačku.

Podmínky

V Javě se podmínky píší úplně stejně, jako ve všech CLike 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)
    System.out.println("Pravda");
System.out.println("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á:

System.out.println("Zadej nějaké číslo");
int a = Integer.parseInt(sc.nextLine());
if (a > 5)
    System.out.println("Zadal jsi číslo větší než 5!");
System.out.println("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 !
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

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 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:

Scanner sc = new Scanner(System.in, "Windows-1250");
System.out.println("Zadej nějaké číslo, ze kterého spočítám odmocninu:");
int a = Integer.parseInt(sc.nextLine());
if (a > 0)
{
    System.out.println("Zadal jsi číslo větší než 0, to znamená, že ho mohu odmocnit!");
    double o = Math.sqrt(a);
    System.out.println("Odmocnina z čísla " + a + " je " + o);
}
System.out.println("Děkuji za zadání");

Konzolová aplikace
Zadej nějaké číslo, ze kterého spočítám odmocninu:
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í

Často můžete vidět použití bloku i v případě, že je pod podmínkou jen jeden příkaz, mnohdy je to totiž přehlednější. Nezapomeňte si naimportovat java.util.Scanner, aby program znal třídu Scanner.

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 třídu Math, která na sobě obsahuje řadu užitečných matematických metod, někdy 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:

Scanner sc = new Scanner(System.in, "Windows-1250");
System.out.println("Zadej nějaké číslo, ze kterého spočítám odmocninu:");
int a = Integer.parseInt(sc.nextLine());
if (a > 0)
{
    System.out.println("Zadal jsi číslo větší než 0, to znamená, že ho mohu odmocnit!");
    double o = Math.sqrt(a);
    System.out.println("Odmocnina z čísla " + a + " je " + o);
}
if (a <= 0)
{
    System.out.println("Odmocnina ze záporného čísla neexistuje!");
}
System.out.println("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:

Scanner sc = new Scanner(System.in, "Windows-1250");
System.out.println("Zadej nějaké číslo, ze kterého spočítám odmocninu:");
int a = Integer.parseInt(sc.nextLine());
if (a > 0)
{
    System.out.println("Zadal jsi číslo větší než 0, to znamená, že ho mohu odmocnit!");
    double o = Math.sqrt(a);
    System.out.println("Odmocnina z čísla " + a + " je " + o);
}
else
{
    System.out.println("Odmocnina ze záporného čísla neexistuje!");
}
System.out.println("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 opět blok { }.

Klíčové slovo 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;
}

System.out.println(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;
}

System.out.println(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:

Scanner sc = new Scanner(System.in, "Windows-1250");
System.out.println("Zadejte číslo v rozmezí 10-20:");
int a = Integer.parseInt(sc.nextLine());
if ((a >= 10) && (a <= 20))
{
    System.out.println("Zadal jsi správně");
}
else
{
    System.out.println("Zadal jsi špatně");
}

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

Scanner sc = new Scanner(System.in, "Windows-1250");
System.out.println("Zadejte číslo v rozmezí 10-20 nebo 30-40:");
int a = Integer.parseInt(sc.nextLine());
if (((a >= 10) && (a <= 20)) || ((a >=30) && (a <= 40)))
{
    System.out.println("Zadal jsi správně");
}
else
{
    System.out.println("Zadal jsi špatně");
}

Switch

Konstrukce switch je převzatá z jazyka C (jako většina gramatiky Javy). 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 switch bychom napsali kód podobný tomuto:

Scanner sc = new Scanner(System.in, "Windows-1250");
System.out.println("Vítejte v kalkulačce");
System.out.println("Zadejte první číslo:");
float a = Float.parseFloat(sc.nextLine());
System.out.println("Zadejte druhé číslo:");
float b = Float.parseFloat(sc.nextLine());
System.out.println("Zvolte si operaci:");
System.out.println("1 - sčítání");
System.out.println("2 - odčítání");
System.out.println("3 - násobení");
System.out.println("4 - dělení");
int volba = Integer.parseInt(sc.nextLine());
float vysledek = 0;
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))
{
        System.out.println("Výsledek: " + vysledek);
}
else
{
        System.out.println("Neplatná volba");
}
System.out.println();
System.out.println("Děkuji za použití kalkulačky.");

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

Všimněte si, že jsme proměnnou výsledek deklarovali na začátku, jen tak do ni můžeme potom přiřazovat. Kdybychom ji deklarovali u každého přiřazení, Java by kód nezkompilovala a vyhodila chybu redeklarace proměnné. Důležité je také přiřadit výsledku nějakou výchozí hodnotu, zde nula, jinak by nám Java vyhubovala, že se snažíme vypsat proměnnou, která nebyla jednoznačně inicializována. Proměnná může být deklarována (založena v paměti) vždy jen jednou. Další vychytávka je kontrola 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í switch:

Scanner sc = new Scanner(System.in, "Windows-1250");
System.out.println("Vítejte v kalkulačce");
System.out.println("Zadejte první číslo:");
float a = Float.parseFloat(sc.nextLine());
System.out.print("Zadejte druhé číslo:");
float b = Float.parseFloat(sc.nextLine());
System.out.println("Zvolte si operaci:");
System.out.println("1 - sčítání");
System.out.println("2 - odčítání");
System.out.println("3 - násobení");
System.out.println("4 - dělení");
int volba = Integer.parseInt(sc.nextLine());
float vysledek = 0;
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))
{
    System.out.println("Výsledek: " + vysledek);
}
else
{
    System.out.println("Neplatná volba");
}
System.out.println();
System.out.println("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 switch 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 switch. 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. Konstrukce switch je v Javě podporován i pro hodnoty Stringové proměnné a to od Javy 7.

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


 

Stáhnout

Staženo 881x (35.09 kB)
Aplikace je včetně zdrojových kódů v jazyce java

 

Předchozí článek
Řešené úlohy k 4. lekci Javy
Všechny články v sekci
Základní konstrukce jazyka Java
Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
68 hlasů
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn College Autor sítě se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity (15)

 

 

Komentáře
Zobrazit starší komentáře (108)

Avatar
Andy
Člen
Avatar
Andy :30.10.2019 12:04

Ahoj, mohl by mi, prosím, někdo poradit, proč tento kód nefunguje? Respektive funguje jen pro první "if", pro všechny ostatní se pak vypíše jen to, co je v posledním "else". Zkoušela jsem různě umístit složené závorky, ale nemělo to kýžený efekt. Není to nic důležitého, jen jsem si tak hrála, ale teď mě irituje, že nemůžu přijít na to, jak to přimět, aby to dělalo to, co chci :)

public static void main(String[] args) {
Scanner sc = new Scanner(System­.in,"utf-8");
System.out.prin­tln("Neužiteč­ná blbost\nNapiš něco:");
String vstup = sc.nextLine()­.trim().toLower­Case();
String odpoved = "";
if (vstup.equals("hov­no"))
odpoved = "Rubiiiiii";
else if (vstup.equals("Ru­bi"))
odpoved = "Hovnooooo";
else if (vstup.equals("Přichá­zí noc"))
odpoved = "Drž hubu!";
if ((vstup.equal­s("hovno")) || (vstup.equals("Ru­bi")) || (vstup.equals("Přichá­zí noc")))
System.out.prin­tln(odpoved);
else
System.out.prin­tln("Co ti na to říct?");

 
Odpovědět
30.10.2019 12:04
Avatar
Odpovídá na Andy
Matúš Olejník:30.10.2019 13:20

Ahoj, keď načítaš vstup tak všetky jeho znaky prevedieš na malé

String vstup = sc.nextLine().trim().toLowerCase();

no, ale potom v podmienkach porovnávaš ten vstup so stringom ktorý má v sebe aj veľké písmená a teda jediná podmienka ktorá má šancu zafungovať je tá prvá.

PS: nikde tu v tutoriáli nie sú písané ify bez zložených zátvoriek, takže odporúčam ich používať :)
takto by to mohlo vyzerať

if(input.equals("hovno")){
    System.out.println("Rubiiiiii");
} else if (input.equals("rubi")){
    System.out.println("Hovnooooo");
} else if (input.equals("přichází noc")) {
    System.out.println("Drž hubu!");
} else {
    System.out.println("Co ti na to říct?");
}

alebo takto

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in,"utf-8");

    System.out.println("Neužitečná blbost\nNapiš něco:");

    String input = sc.nextLine().trim().toLowerCase();

    switch (input){
        case "hovno" : System.out.println("Rubiiiiii");
            break;
        case "rubi" : System.out.println("Hovnooooo");
            break;
        case "přichází noc" : System.out.println("Drž hubu!");
            break;

        default: System.out.println("Co ti na to říct?");
    }
}
Odpovědět
30.10.2019 13:20
/* I am not sure why this works but it fixes the problem */
Avatar
Andy
Člen
Avatar
Odpovídá na Matúš Olejník
Andy :30.10.2019 13:44

To byla teda pěkně hloupá chyba, sypu si popel na hlavu. Mnohokrát děkuji za radu :) Ještě bych se chtěla zeptat, zda je lepší používat if a else, nebo switch, pokud chci dát více podmínek. Co se týče přehlednosti, přijde mi to nastejno, tak jestli je vhodnější to, nebo ono :)

 
Odpovědět
30.10.2019 13:44
Avatar

Člen
Avatar
:28. ledna 19:29

Hezká lekce.

 
Odpovědět
28. ledna 19:29
Avatar
charliho
Člen
Avatar
charliho:22. března 12:30

Ahoj všem, prosím o radu, postupuji dle tohoto návodu a tvořím si jednoduchou kalkulačku. Chtěl bych aby byla ošetřená proti všem špatným zadáním uživatele. Podařilo se mi vyřešit a-z A-Z, nějaké další znaky, ale jak ošetřím, aby mi uživatel nezadal speciální znaky typu +-*@{ apod. Prosím o radu.

Můj kód na ošetření znaků je takovýto, ale nevím zdali je správně.

if (!Svolba.matches("[a-zA-Z_/*--+,.;&@%<>´=]") && Svolba != null && !Svolba.isEmpty())

Problém je, že pokud zadám jeden znak, vše je v pořádku a podmínka se provede se jako true. Ale pokud zadám dva a více znaků už skončím na pádu aplikace (kvůli parsování proměnné na integer).

Dodám, že proměnná Svolba je string a hned za splnění podmínky ji parsuji na integer do proměnné "volba".

Všem předem díky za pomoc.

 
Odpovědět
22. března 12:30
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
charliho
Člen
Avatar
Odpovídá na charliho
charliho:22. března 12:47

Asi jsem si odpověděl sám. Ověřovat, zdali je vstup pouze číslo bych měl asi přes hasNextInt() že :D

Díky

 
Odpovědět
22. března 12:47
Avatar
charliho
Člen
Avatar
Odpovídá na charliho
charliho:22. března 14:38

Je lepší použít try-catch na ošetření vstupu uživatele nebo se snažit můj problém vyřešit jinak? Díky

 
Odpovědět
22. března 14:38
Avatar
Mike
Člen
Avatar
Mike:15. května 17:57

Ahoj, sim, není mi jasné, proč je v posledních dvou příkladech na předposledním řádku
System.out.prin­tln();
Jaký to má důvod?
Díky

 
Odpovědět
15. května 17:57
Avatar
Alesh
Překladatel
Avatar
Odpovídá na Mike
Alesh:15. května 18:34

Metoda println(text) na rozdíl od metody print(text) nejen vypíše text, ale po jeho vypsání odřádkuje. Pokud text není zadán, pak metoda pouze jen odřádkuje. V kódu prostě slouží jen k tomu, aby se tam jednou odřádkovalo a tím to vypadalo lépe a nebyly ty řádky namaštěný hned za sebou.

 
Odpovědět
15. května 18:34
Avatar
Mike
Člen
Avatar
Odpovídá na Alesh
Mike:15. května 18:38

Bingo, je to jasné
Už to vidím, musel jsem ale spustit kód a pak to odřádkování tam je
V tabulce pod totiž ten prázdný řádek chybí
To mě zmátlo
Díky

 
Odpovědět
15. května 18:38
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 118. Zobrazit vše