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

Java Základní konstrukce Podmínky (větvení) American English version English version

Unicorn College ONEbit hosting Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci, Typový systém podruhé: Datové typy, 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í 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 !

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. 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 { }.

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

Switch je konstrukce, 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 switche 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í switche:

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 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 je v Javě podporován i pro hodnoty stringové proměnné a to od Javy 7.

To bychom měli. V příští lekci, Cykly v Javě, nás čekají pole a cykly, tím dovršíme základní znalosti, máte se na co těšit :)


 

Stáhnout

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

 

 

Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
53 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.
Miniatura
Všechny články v sekci
Základní konstrukce jazyka Java
Miniatura
Následující článek
Cvičení k 5. lekci Javy
Aktivity (9)

 

 

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

Avatar
Michal Šmahel:14.8.2017 0:08

Nech si vypsat vstup před a po parsování. Co se týče porovnání řetězců, není to těžké. Podívej se na funkci equals().

// Instance Skeneru
Scanner sc = new Scanner(System.in, "Windows-1250");

// Vstup
String vstup = sc.nextLine();

/* <nedoporucuji> */
// Porovnání řetězců
if (vstup.equals("1")) {
        System.out.println("Vybrána volba č. 1");
}
/* </nedoporucuji> */

/* <lepsi> */
// Parsujeme na ciselny datovy typ - napr. pouzity int
int vstupCislo = Integer.parseInt(vstup);

// Porovnani cisel
if (vstupCislo == 1) {
        System.out.println("Vybrána volba č. 1");
}
/* </lepsi> */

Stále ovšem platí to, co jsem psal v předchozím komentáři: Pokud pracuješ s čísly, pracuj s nimi ve vhodném číselném datovém typu, string není pro běžná čísla vhodný.

Odpovědět 14.8.2017 0:08
Nejdůležitější je motivace, ovšem musí být doprovázena činy.
Avatar
Rico ThreeDmax:14.8.2017 19:32

Bezva diky moc

 
Odpovědět 14.8.2017 19:32
Avatar
Radka Jánská:25.8.2017 22:36

Ahoj všichni, řeším dilema s klávesnicí. Používáte při programování českou nebo anglickou klávesnici? Vzhledem k tomu, že Java vychází z angličtiny mi přijde logické používat anglickou, ale co potom, když do stringu píšete český text nebo ho potřebujete dát do českých (dvojitých) úvozovek? Přehazujete klávesnici? Na druhou stranu, pokud používáte českou klávesnici, jak píšete znaky, které nemá (anglické uvozovky, větší než / menší než, složené závorky, hranaté závorky apod.)? Předem děkuji za podněty.

 
Odpovědět 25.8.2017 22:36
Avatar
Odpovídá na Radka Jánská
Petr Štechmüller:25.8.2017 22:49

Ahoj, jde o zvyk. Já všechno píšu na české klávesnici. Ty speciální znaky lze psát pomoci pravého altu (alt gr).
"<" = "alt gr + ?"
">" = "alt gr + ."
"{" = "alt gr + b"
"}" = "alt gr + n"
"[" = "alt gr + f"
"[" = "alt gr + g"

Zbytek zkratek najdeš na netu...

Odpovědět  +1 25.8.2017 22:49
Pokud spolu kód a komentář nekorespondují, budou patrně oba chybné
Avatar
patrik.valkovic
Šéfredaktor
Avatar
Odpovědět 25.8.2017 22:59
Nikdy neumíme dost na to, abychom se nemohli něco nového naučit.
Avatar
Zdeněk Lenk
Člen
Avatar
Zdeněk Lenk:4. února 9:51

Zdravím,

když do níže uvedeného programu zadám v NetBeans v konzoli 0 nebo záporné číslo, tak mi jako odpověd nevyběhne tato hláška: Odmocnina ze záporného čísla neexistuje! Čím to může být? Program jsem jen zkopíroval z těchto stránek a neupravil.

package podminka3;

import java.util.Scanner;

public class Podminka3
{
public static void main(String[] args) {

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

 
Odpovědět 4. února 9:51
Avatar
Luke Streit
Člen
Avatar
Odpovídá na Zdeněk Lenk
Luke Streit:20. února 11:02

Ten kód co jsi zde zmínil jsem hodil do IDEA a normálně to fungovalo, ale ještě mě napadla jedna věc.

Zkus místo - if(a<=0) dát jenom else - protože ty tím prvním ifem říkáš, že to co je větší než 0, tak ti to odmocninu vypočítá a z toho ti automaticky vyplývá, že když ta podmínka nebude splněna, tak ti to tu odmocninu nevypočte...Ale fungovat by měl i ten kód co jsi zde zmínil...

 
Odpovědět 20. února 11:02
Avatar
Filip Gola
Člen
Avatar
Filip Gola:15. března 11:23

Dobrý deň chcem sa opýať aký je rozdiel medzi príkazom názovScaneru.nex­tLine() a nazovScanneru­.next()

package com.filip;

import java.util.Scanner;

public class Main {

public static void main(String[] args) {

Scanner scan = new Scanner(System.in);
boolean conti = true;
while (conti) {
System.out.prin­tln("Write 3 numbers");
int num1 = scan.nextInt();
int num2 = scan.nextInt();
int num3 = scan.nextInt();
if ((num1 > num2) && (num1 > num3)) {
System.out.prin­tln("The greatest is: " + num1);
} else if ((num2 > num1) && (num2 > num3)) {
System.out.prin­tln("The greatest is: " + num2);

} else {
System.out.prin­tln("The greatest is: " + num3);
}
System.out.prin­tln("Do you want to continue in program? [yes / no]");
String pokracuj = scan.nextLine();
// ked to dam scan.next(); tak to robi to co ma ale chcem vediet preco :)

conti = (pokracuj.equ­alsIgnoreCase("y­es")? true : false);
}

}
}

Editováno 15. března 11:25
 
Odpovědět 15. března 11:23
Avatar
Rasinsky
Člen
Avatar
Rasinsky:26. července 14:04

Scanner.next() precita vstup iba po prvu medzeru, neprecita viac retazcov oddelenych medzerou. A tiez ponecha kurzor na povodnom riadku po precitani, zvysne retazce oddelene medzerou "ostanu" stale nacitane.

Scanner.nextLine() precita cely riadok az do konca, a nastavi kurzor na novy riadok

To s tym nastavovanim kurzoru:
ak pouzijes napr

Scanner sc=new Scanner(System.in);
        System.out.println("zadaj prvy text: ");

        String str1=sc.next();

        System.out.println("Prvy text "+str1);

        System.out.println("zadaj druhy text: ");

        String str2=sc.next();

        System.out.println("druhy text:  "+str2);

        sc.close();

ak v takomto pripade zadas text: aaa bbb, tak ta ani nepusti zadat druhy text, kedze ostane kurzor na tom istom riadku a nacita dalsi retazec po dalsiu medzeru. Vystup by bol v tomto pripade

zadaj prvy text:
aaa bbb
Prvy text aaa
zadaj druhy text:
druhy text: bbb

V tvojom pripade

// ked to dam scan.next(); tak to robi to co ma ale chcem vediet preco :)

to robi to iste lebo ocakavas len jeden retzec / jedno slovo/ ktory kontrolujes [yes / no]

 
Odpovědět 26. července 14:04
Avatar
Karel Klíč
Člen
Avatar
Karel Klíč:15. září 10:37

V tutoriálu větvení v druhém programu vám chybí deklarace nebo definice Scanner sc = new Scanner(System­.in,"Windows-1250"); a pak je metoda volána. Tudíž vyhodí chybu, protože Scanner nemá definovanou proměnou do které data načíst. S pozdravem Karel

 
Odpovědět 15. září 10:37
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 100. Zobrazit vše