V šestém díle překladu oficiálního Java tutoriálu se zaměříme na výrazy, příkazy, bloky a struktury pro řízení toku programu.
Výrazy, příkazy a bloky
Nyní, když rozumíte proměnným a operátorům, je čas popovídat si o výrazech, příkazech a blocích. Operátory mohou být použity ve výrazech, které vracejí hodnotu; výrazy jsou základní součástí příkazů; příkazy mohou být seskupeny do bloků.
Výrazy
Výraz je konstrukce složená z proměnných, operátorů a volání metod, které jsou složeny pomocí odpovídající syntaxe jazyka a vyúsťují v jednu hodnotu. Již jste mohli vidět příklady výrazů, zde jsou vyznačeny podtržením:
int cadence = 0;
nejakePole[0] = 100;
System.out.println("Element 1 na indexu 0: " + nejakePole[0]);
int vysledek = 1 + 2; // výsledek je nyní 3
if(hdonota1 == hodnota2) System.out.println("hodnota1 == hodnota2");
Datový typ hodnoty vrácené výrazem záleží na tom, z čeho se výraz skládá. Výraz cadence = 0
vrátí int
, protože přiřazovací operátor vrací hodnotu takového typu, jaký je na jeho levé straně; v tomto případě cadence
je int
. Jak můžete vidět na jiných příkladech, výraz může stejně dobře vracet jakýkoliv jiný typ, jako je boolean
nebo string
.
Programovací jazyk Java vám dovolí konstruovat složené výrazy z různých menších výrazů, dokud typ dat, požadovaný jednou částí výrazu, odpovídá typu dat další. Zde je příklad složeného výrazu:
1 * 2 * 3
V tomto speciálním případě je pořadí, v jakém se výraz vykonává, nedůležité, protože výsledek násobení nezávisí na pořadí; výsledek je vždy stejný, lhostejno v jakém pořadí je násobení vykonáváno. Nicméně toto neplatí pro všechny příklady. Například následující výraz vrací různé výsledky podle toho, zda se provede dřív sčítání nebo dělení:
x + y / 100 // dvojsmyslné
Můžete přesně specifikovat, která operace se provede dříve použitím kulatých závorek (
a )
. Například abyste udělali předchozí příklad jednoznačný, stačí provést tuto změnu:
(x + y) / 100 // jednoznačné, doporučované
Pokud přesně nespecifikujeme, v jakém pořadí se bude výraz vyhodnocovat, odvodí se podle priority operátorů, použitých ve výrazu. Operátor, který má vyšší přednost, se provede dříve. Například operátor dělení má větší prioritu než operátor sčítání. Právě proto jsou následující výrazy shodné:
x + y / 100
x + (y / 100) // jednoznačné, doporučované
Když píšete složité výrazy, je dobré přesně označit, která část se má provést dříve. Tato praktika činí kód lépe čitelným a udržovatelným.
Příkazy
Příkazy jsou zhruba shodné s větami běžných jazyků. Příkaz tvoří kompletní jednotku vykonávání kódu. Následující typy výrazů mohou být použity jako příkazy pouhým ukončením středníkem (;
).
- přiřazovací výrazy
- jakékoliv použití
++
nebo--
- volání metod
- tvoření objektů
Tyto příkazy jsou nazývány výrazové příkazy. Zde je několik příkladů výrazových příkazů:
nejakaHodnota = 8933.234; // příkaz přiřazení
nejakaHodnota++; // příkaz inkrementace
System.out.println("Hello World!"); // příkaz volání metody
Bicycle mojeKolo = new Bicycle(); // příkaz vytvoření objektu
Společně s výrazovými příkazy jsou zde další dva druhy příkazů: deklarativní příkazy a příkazy toku programu. Deklarativní příkazy deklarují proměnnou. Doteď jste viděli spoustu příkladů deklarativních příkazů:
double nejakaHodnota = 8933.234; // deklarativní příkaz
Konečně, příkazy toku programu regulují, v jakém pořadí budou jednotlivé příkazy vykonávány. Více se o nich dovíme dále v této lekci.
Bloky
Blok je skupina žádného nebo více příkazů uzavřena mezi složené závorky ({
a }
), která může být použita kdekoli místo normálního příkazu. Následující příklad ilustruje bloky:
class BlockDemo {
public static void main(String[] args) {
boolean podminka = true;
if (podminka) { // začátek 1. bloku
System.out.println("Podmínka je pravdivá.");
} // konec 1. bloku
else { // začátek 2. bloku
System.out.println("Podmínka je nepravdivá.");
} // konec 2. bloku
}
}
Příkazy toku programu
Příkazy jsou uvnitř zdrojového kódu vykonávány od prvního směrem dolů tak, jak jsou v kódu napsány. Příkazy toku programu nicméně zastaví tok a umožňují váš program řídit, opakovat a větvit, umožňují vašemu programu podmíněně vykonávat příslušné bloky kódu. Tato sekce popisuje rozhodovací příkazy (if-then
, if-then-else
, switch
), příkazy smyčky (for
, while
, do-while
) a příkazy přesunu (break
, continue
, return
) podporované programovacím jazykem Java.
Příkazy if-then a if-then-else
Příkaz if-then
Příkaz if-then
je nejzákladnějším ze všech příkazů toku programu. Říká, aby část kódu byla vykonána pouze tehdy, když se příslušný test vyhodnotí jako true
(pravda). Například třída Bicycle
může povolit použití brzd pouze tehdy, když je kolo již v pohybu. Jedna z možných implementací metody applyBrakes
může vypadat takto:
void applyBrakes(){
if (jeKoloVPohybu){ // část "if" (když): kolo se musí pohybovat
momentalniRychlost--; // část "then" (tak): sniž současnou rychlost
}
}
Jestliže se podmínka vyhodnotí jako false
(což znamená, že kolo není v pohybu),
program přeskočí na konec příkazu if-then
.
Dále, složené závorky jsou dobrovolné, pokud část „then“ obsahuje pouze jeden příkaz:
void applyBrakes(){
if (jeKoloVPohybu) momentalniRychlost--; // stejné jako výše, ale bez složených závorek
}
Vynechávání závorek je otázkou vašeho zvyku, činí to však kód více křehčím. Pokud v budoucnu budete chtít do části „then“ přidat nový příkaz, můžete zapomenout nově potřebné složené závorky. Kompilátor tuto chybu nemůže odhalit, podle něj je takový kód správný.
Příkaz if-then-else
Příkaz if-then-else
poskytuje druhou cestu vykonávání programu, když část
„if“ se vyhodnotí jako false
. Můžete použít příkaz if-then-else
v metodě applyBrakes
pro provedení nějaké akce, když kolo není v pohybu. V tomto případě jednoduše vytiskneme chybovou zprávu, pokud kolo není v pohybu.
void applyBrakes(){
if (jeKoloVPohybu) {
momentalniRychlost--;
} else {
System.err.println("Kolo již stojí!");
}
}
Následující program dává školní známku, založenou podle výsledku testu: A pro skóre nad 90 %, B pro skóre nad 80 % atd.:
class IfElseDemo {
public static void main(String[] args) {
int testscore = 76;
char znamka;
if (testscore >= 90) {
znamka = 'A';
} else if (testscore >= 80) {
znamka = 'B';
} else if (testscore >= 70) {
znamka = 'C';
} else if (testscore >= 60) {
znamka = 'D';
} else {
znamka = 'F';
}
System.out.println("Vase znamka je " + znamka);
}
}
Výstup tohoto programu je:
Vase znamka je C
Jak si můžete všimnout, hodnota testscore
může vyhovět více než jedné podmínce ve složeném příkaze: 76 >= 70
a
76 >= 60
. Nicméně, jakmile je jednou podmínka splněna, odpovídající úsek programu je vykonán (znamka = 'C';)
a zbytek podmínek není vyhodnocen.
Příkaz switch
Na rozdíl od if-then
a if-then-else
, příkaz switch
povoluje libovolný počet cest, kterými se program vydá. switch
pracuje s těmito primitivními typy: byte
, short
, char
a int
. Taktéž pracuje s výčtovými typy a se speciálními třídami obalujícími primitivní datové typy: Character
, Byte
, Short
a Integer
. O všech těchto záležitostech se dozvíte v dalších dílech seriálu.
Následující program definuje hodnotu typu int
nazvanou mesic
, jejíž hodnota reprezentuje aktuální měsíc. Následující program vypíše název měsíce s použitím příkazu switch
.
class SwitchDemo {
public static void main(String[] args) {
int mesic = 8;
switch (mesic) {
case 1: System.out.println("Leden"); break;
case 2: System.out.println("Únor"); break;
case 3: System.out.println("Březen"); break;
case 4: System.out.println("Duben"); break;
case 5: System.out.println("Květen"); break;
case 6: System.out.println("Červen"); break;
case 7: System.out.println("Červenec"); break;
case 8: System.out.println("Srpen"); break;
case 9: System.out.println("Září"); break;
case 10: System.out.println("Říjen"); break;
case 11: System.out.println("Listopad"); break;
case 12: System.out.println("Prosinec"); break;
default: System.out.println("Špatný měsíc.");break;
}
}
}
V tomto případě je na standardní výstup vytištěno: "Srpen".
Tělo příkazu switch
je známo jako switch blok. Jakýkoli příkaz, který
je ve switch bloku, by měl být označen pomocí slov case
nebo default
. Příkaz switch
vyhodnotí svůj výraz a po porovnání vykoná odpovídající blok case
.
Samozřejmě totéž můžete uskutečnit pomocí příkazů if-then-else
:
int mesic = 8;
if (mesic == 1) {
System.out.println("Leden");
} else if (mesic == 2) {
System.out.println("Únor");
}
. . . // a tak dále
Rozhodnutí, kdy použijete if-then-else
a kdy switch
, záleží na vašem mínění. Měli byste se opřít o čitelnost kódu a o obdobné faktory. Příkaz if-then-else
může být použit k rozhodování nad několika hodnotami a složitými podmínkami, zatímco příkaz switch
může být použit k rozhodování pouze nad jednoduchou celočíselnou nebo výčtovou hodnotou.
Jediným bodem zájmu je příkaz break
po každém case
. Každý příkaz break
ukončí provádění daného příkazu switch
. Tok programu pokračuje po ukončovací složené závorce bloku switch
. Příkazy break
jsou nezbytné, protože bez nich by každý příkaz case
propadl; to znamená, že bez přímého zadání příkazu break
tok programu bude pokračovat skrz další příkazy case
. Následující program ukazuje, kdy může být užitečné, že příkazy case
propadají:
class SwitchDemo2 {
public static void main(String[] args) {
int mesic = 2;
int rok = 2000;
int pocetDni = 0;
switch (mesic) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
case 12:
pocetDni = 31;
break;
case 4:
case 6:
case 9:
case 11:
pocetDni = 30;
break;
case 2:
if ( ((rok % 4 == 0) && !(rok % 100 == 0))
|| (rok % 400 == 0) )
pocetDni = 29;
else
pocetDni = 28;
break;
default:
System.out.println("Špatný měsíc.");
break;
}
System.out.println("Počet dnů v měsíci = " + pocetDni);
}
}
Zde je výstup programu.
Počet dnů v měsíci = 29
Technicky není poslední příkaz break
, protože tok programu přejde za příkaz switch
i bez něj. Nicméně doporučujeme používat příkaz break
i na konci, protože váš kód činí lépe modifikovatelným a méně náchylný k chybám. Sekce default
zachytává ten případ, kdy není žádná sekce case
vykonána.
Příkazy while a do-while
Příkaz while
(nebo také smyčka while) opakovaně vykonává kód, dokud je podmínkový výraz true
.
Jeho syntaxe může být zhrnuta takto:
while (podmínkovýVýraz) {
přikaz(y)
}
Příkaz while
vyhodnotí podmínkovýVýraz, ktyrý musí vracet hodnotu typu
boolean
. Jestliže je jeho hodnota true
, příkaz while
vykoná přikaz(y) v bloku while
. Příkaz while
pokračuje vyhodnocováním podmíkového výrazu a vykonáváním bloku, dokud podmínka nevrátí false
. Použití příkazu while
k vypsání hodnot od jedné do desíti může být uděláno stejně jako v následujícím programu:
class WhileDemo {
public static void main(String[] args){
int cislo = 1;
while (cislo < 11) {
System.out.println("Číslo je nyní: " + cislo);
cislo++;
}
}
}
Můžete také udělat nekonečnou smyčku použitím následujícího úryvku kódu:
while (true){
// zde bude váš kód
}
Programovací jazyk Java taktéž poskytuje smyčku do-while
, která se dá shrnout takto:
do {
příkaz(y)
} while (podmínkovýVýrat);
Rozdíl mezi do-while
a while
je, že smyčka do-while
vykoná svůj podmínkový výraz až po vykonání příkazů smyčky. Proto jsou příkazy v bloku do
vždy vykonány alespoň jednou, jak ukazuje následující program:
class DoWhileDemo {
public static void main(String[] args){
public static void main(String[] args){
int cislo = 1;
do {
System.out.println("Číslo je nyní: " + cislo);
cislo++;
} while (cislo < 11);
}
}
}
Příkaz for
Příkaz for
poskytuje komplexní způsob, jak projít přes řadu hodnot. Programátoři o tomto příkazu často mluví jako o „cyklu for“, protože je to cesta, jak opakovaně vykonávat kód, dokud není splněna podmínka. Obecná forma příkazu for
může být vyjádřena jako v následující ukázce:
for (inicializace; podmínka; inkrementace) {
přikaz(y)
}
Když používáte tuto verzi příkazu for
, mějte na paměti, že:
- Výraz inicializace připraví smyčku; je vykonán pouze jednou, když smyčka začíná.
- Když výraz podmínky vrátí hodnotu
false
, smyčka končí. - Výraz inkrementace je vykonán po každém průchodu smyčkou; jedná se o perfektní místo, kde provést inkrementaci (zvětšení) nebo dekrementaci (zmenšení) hodnoty.
Následující program ukazuje příklad, kdy je smyčka for
použita k výpisu čísel od 1 do 10:
class ForDemo {
public static void main(String[] args){
for(int i=1; i<11; i++){
System.out.println("Cislo je: " + i);
}
}
}
Výstup tohoto programu je:
Cislo je: 1
Cislo je: 2
Cislo je: 3
Cislo je: 4
Cislo je: 5
Cislo je: 6
Cislo je: 7
Cislo je: 8
Cislo je: 9
Cislo je: 10
Všimněte si, jak kód deklaruje proměnou uvnitř inicializačního výrazu. Viditelnost proměnné je od své deklarace po konec bloku for
, takže může být použita i uvnitř výrazů podmínky a inkrementace. Jestliže proměnná, která kontroluje příkaz for
, není potřeba mimo smyčku, je nejlepší místo k její deklaraci v inicializačním výrazu. Pro kontrolu smyčky for
se často používají proměnné s názvy i
, j
a k
; jejich deklarováním uvnitř inicializačního výrazu omezujete jejich životnost a zabraňujete chybám.
Všechny 3 výrazy smyčky for
jsou nepovinné; nekonečná smyčka může být vytvořena např. takto:
for ( ; ; ) { // nekonečná smyčka
// zde bude váš kód
}
Příkaz for
má taktéž jinou formu, určenou pro procházení polí a kolekcí.
Tato forma je někdy nazývána rozšířený for a může váš kód udělat kratším a lépe čitelným. Pro demonstraci použijeme následující pole celých čísel, obsahující hodnoty od 1 do 10:
int[] cisla = {1,2,3,4,5,6,7,8,9,10};
Následující program používá rozšířenou formu smyčky for
pro průchod polem:
class EnhancedForDemo {
public static void main(String[] args){
int[] cisla = {1,2,3,4,5,6,7,8,9,10};
for (int cislo : cisla) {
System.out.println("Cislo je: " + cislo);
}
}
}
V tomto příkladě proměnná item drží jednu hodntu z pole čísel. Výstup programu je stejný jako předtím:
Cislo je: 1
Cislo je: 2
Cislo je: 3
Cislo je: 4
Cislo je: 5
Cislo je: 6
Cislo je: 7
Cislo je: 8
Cislo je: 9
Cislo je: 10
Doporučujeme používat tuto formu příkazu for
místo té základní, kdekoli to jen jde.
Příkazy pro ovlivnění průběhu cyklu
Příkaz break
Příkaz break
má dvě formy: označenou a neoznačenou. Neoznačenou formu jste mohli vidět, když jsme se bavili o příkazu switch
.
Neoznačený příkaz break
můžete použít k násilnému zastavení příkazů for
, while
nebo do-while
, jak ukazuje následující program:
class BreakDemo {
public static void main(String[] args) {
int[] poleCelychCisel = { 32, 87, 3, 589, 12, 1076,
2000, 8, 622, 127 };
int hledane = 12;
int i;
boolean nalezeno = false;
for (i = 0; i < poleCelychCisel.length; i++) {
if (poleCelychCisel[i] == hledane) {
nalezeno = true;
<strong>break;</strong>
}
}
if (nalezeno) {
System.out.println("Cislo " + hledane
+ " nalezeno na indexu " + i);
} else {
System.out.println(hledane
+ " neni v poli");
}
}
}
Tento program hledá číslo 12 v poli. Příkaz break
, vydíte jej tučně, ukončí smyčku for
, když je hodnota nalezena. Tok programu se poté přesune na výpis hlášení a ukončí se.
Výstup programu je:
Cislo 12 nalezeno na indexu 4
Neoznačený příkaz break
ukončí nejbližší příkaz switch
, for
, while
nebo do-while
, ale označený break
ukončí i vnější. Následující program je podobný předchozímu, ale používá vnořené smyčky for
pro nalezení hodnoty ve dvourozměrovém poli. Když je hodnota nalezena, označený break
ukončí vnější smyčku for
(označenou jako „hledani“):
class BreakWithLabelDemo {
public static void main(String[] args) {
int[][] poleCelychCisel = { { 32, 87, 3, 589 },
{ 12, 1076, 2000, 8 },
{ 622, 127, 77, 955 }
};
int hledane = 12;
int i;
int j = 0;
boolean nalezeno = false;
hledani:
for (i = 0; i < poleCelychCisel.length; i++) {
for (j = 0; j < poleCelychCisel[i].length; j++) {
if (poleCelychCisel[i][j] == hledane) {
nalezeno = true;
break hledani;
}
}
}
if (nalezeno) {
System.out.println("Cislo " + searchfor +
" nalezeno na indexu " + i + ", " + j);
} else {
System.out.println(searchfor
+ " neni v poli");
}
}
}
Zde je výstup programu:
Cislo 12 nalezeno na indexu 1, 0
Příkaz break
ukončil označený příkaz, nepřenesl tok programu na označené místo. Tok programu byl přesunut na konec označeného (ukončeného) příkazu.
Příkaz continue
Příkaz continue
ukončí současnou iteraci smyčky for
, while
nebo do-while
. Neoznačená forma příkazu přeskočí na konec bloku smyčky a pokračuje vyhodnocením výrazu promínky. Následující program prochází přes String
, počítajíc počet výskytů písmene „p“. Jestliže současné písmenko není „p“, příkaz continue
přeskočí zbytek smyčky a pokračuje dalším znakem. Jestliže to je „p“, program zvýší počet výskytů.
class ContinueDemo {
public static void main(String[] args) {
String prohledejMe = "peter piper picked a peck of pickled peppers";
int max = prohledejMe.length();
int pocetPecek = 0;
for (int i = 0; i < max; i++) {
// zajímá nás pouze p
if (prohledejMe.charAt(i) != 'p')
continue;
// zpracuj p
pocetPecek++;
}
System.out.println("Nalezeno " + numPs + " výskytů písmene p v řetězci.");
}
}
Zde je výstup programu:
Nalezeno 9 výskytů písmené p v řetězci.
Abyste viděli efekt příkazu continue
, odstraňte jej a příkaz překompilujte. Když program spustíte, zjistíte, že pracuje špatně, protože nalezl 35 „p“ místo 9.
Označený příkaz continue
přeskočí zbytek iterace oznčené smyčky. Následující program používá dvě vložené smyčky k„nalezení podřetězce v„řetězci. Dvě vložené smyčky jsou potřeba: jedna iteruje přes hledaný podřetězec a jedna přes prohledávaný řetězec.
class ContinueWithLabelDemo {
public static void main(String[] args) {
String prohledejMe = "Look for a substring in me";
String podretezec = "sub";
boolean nalezeno = false;
int max = prohledejMe.length() - podretezec.length();
test:
for (int i = 0; i <= max; i++) {
int n = podretezec.length();
int j = i;
int k = 0;
while (n-- != 0) {
if (prohledejMe.charAt(j++)
!= substring.charAt(k++)) {
continue test;
}
}
nalezeno = true;
break test;
}
System.out.println(nalezeno ? "Nalezeno" :
"Nenalezeno");
}
}
Zde je výstup tohoto programu:
Nalezeno
Příkaz return
Poslední dnes probíraný příkaz je return
.
Příkaz return
ukončí právě vykonávanou metodu a tok programu se vrátí na místo, kde byla metoda zavolána. Příkaz return
má dvě formy: jedná vrací hodnotu a jedna ne. Pro vrácení hodnoty jednoduše napište hodnotu (nebo výraz, který ji spočte) za klíčové slovo return
.
return ++count;
Typ vrácených dat musí být shodný s typem deklarovaným v hlavičce metody. Když je metoda deklarována s void
, použijte formu příkazu return
, která nevrací hodnotu.
return;
V příštím dílu
Tímto dílem jsme se dobrali konce základních principů programovacího jazyka Java a nyní se budeme příští 3 díly věnovat tématu tříd a objektů, konkrétně hned v dalším díle základům tohoto tématu.