Image
22.6.2016 0 Comments

Java pod lupou I. /6.časť

Späť na úvod >> Späť na programovanie >> Späť na seriál

Príkazy (dokončenie)

V šiestom pokračovaní seriálu Java pod lupou dokončíme rozprávanie o príkazoch jazyka Java. Na zopakovanie: dosiaľ sa hovorilo okrem už známych deklaračných a výrazových príkazov o podmienkovom príkaze if. V tejto časti sa čitateľ dozvie o druhom podmienkovom príkaze switch a o príkazoch cyklu while, do a for.

Podmienený príkaz switch

Ďalším príkazom, pomocou ktorého možno vetviť vykonávanie programu v závislosti od určitej podmienky, je príkaz switch. Ako napovedá jeho názov, ide doslova o prepínač, ktorý vyberie vetvu programu na základe hodnoty nejakého výrazu. Takýto kód možno naprogramovať aj pomocou zreťazených príkazov if, ale pri použití príkazu switch ušetríme dačo miesta a ešte k tomu zabránime viacnásobnému vyhodnocovaniu testovaného výrazu (čo oceníme v prípade, že tento výraz má nejaké vedľajšie účinky).

Ako vyzerá príkaz switch? Jeho syntax je nasledujúca:

switch ( výraz )
{
case hodnota1 :
    príkazy
case hodnota2 :
    príkazy
 
    // ...
 
default:
    príkazy
}

Pozrime sa na túto schému podrobnejšie. Za kľúčovým slovom switch nájdeme v okrúhlych zátvorkách testovaný výraz. Ten musí mať niektorý z typov char, byte, short alebo int. Za výrazom nasleduje v zložených zátvorkách uzavretý blok príkazov. V tomto bloku sa na určitých miestach vyskytujú tzv. návestia v tvare case hodnota. Jednotlivé hodnoty v návestiach musia byť rôzne a kompatibilné s typom výrazu.

Keď program počas behu dospeje k príkazu switch, určí hodnotu výrazu a postupne bude prehľadávať hodnoty uvedené v návestiach v bloku príkazov. Ak nájde zhodu, začne vykonávať príkazy za nájdeným návestím až do konca tela príkazu switch. V prípade, že ani jedno návestie neobsahuje hľadanú hodnotu, program pokračuje príkazmi za návestím default. Toto návestie nie je povinné, a ak sa v tele príkazu switch nenachádza, program jednoducho pri neúspešnom hľadaní zhody príkaz switch preskočí.

Podobne ako v C++ sa v okamihu nájdenia zhody ďalšie návestia ignorujú a program takpovediac „prepadáva“ cez jednotlivé úseky príkazov, oddelené návestiami, až kým dospeje na koniec príkazu switch. To ilustruje nasledujúci príklad:

class OneTwo
{
  public static void main(String[] args)
  {
    show(3);
    show(2);
    show(1);
  }
  static void show(int n)
  {
    switch (n)
    {
    case 1:
      System.out.print("one ");
    case 2:
      System.out.print("two ");
    default:
      System.out.print("other");
    }
    System.out.println("");
  }
}

Tento program po spustení vypíše riadky:

other
two other
one two other

pretože po odskoku na návestie case 1, resp. case 2, a vypísaní príslušného textu program jednoducho pokračuje ďalšími príkazmi v tele switch. Ak tomu chceme zabrániť, treba použiť iný príkaz break, ktorý v tele príkazu switch spôsobí, že program z tohto tela vyskočí a bude pokračovať prvým príkazom za celým blokom switch.

Upravená metóda show() bude potom vyzerať takto:

static void show(int n)
{
  switch (n)
  {
  case 1:
    System.out.print("one");
    break;
  case 2:
    System.out.print("two");
    break;
  default:
    System.out.print("other");
  }
  System.out.println("");
}

S takouto verziou show() už program vypíše správny výstup:

other
two
one

Príkaz cyklu while

Dva predchádzajúce príkazy, if a switch, patria medzi príkazy selekcie, resp. alternatívy, či sa im hovorí aj podmienkové príkazy. Druhý okruh príkazov, na ktorých je založená teória štruktúrovaného programovania, sú príkazy cyklu.

Na realizáciu jednoduchého cyklu s testovaním podmienky na začiatku slúži príkaz while. Syntax tohto príkazu je:

while ( podmienka )
    príkaz

Výraz podmienka musí byť podobne ako v príkaze if typu boolean, iný typ prekladač odmietne. Na mieste príkazu môže stáť aj zložený príkaz, teda blok príkazov, uzavretý v zložených zátvorkách.

Príkaz while sa vykonáva týmto spôsobom: najprv sa vyhodnotí podmienkový výraz. Ak je jeho hodnota pravdivá, teda true, vykoná sa príkaz a opätovne sa riadenie programu vráti akoby pred príkaz while. Ak bude hodnota podmienky nepravdivá, cyklus while končí, príkaz sa ďalej vykonávať nebude. Treba si uvedomiť, že ak bude už na začiatku cyklu podmienka nesplnená, telo cyklu sa nevykoná ani raz.

Slovo „while“ v angličtine znamená „kým, pokiaľ“ a podľa toho sa aj cyklus while správa: vykonáva príkaz, kým je splnená určitá podmienka. Podmienka sa testuje pred vykonaním tela cyklu.

Ukážme si príklad na tento cyklus. Chceme nájsť najmenšieho spoločného deliteľa dvoch čísel uložených v premenných a a b. Použijeme známy Euklidov algoritmus:

while (a != b)
{
  if (a > b)
    a = a – b;
  else
    b = b – a;
}

Cyklus bude „cykliť“ dovtedy, kým budú hodnoty premenných a a b rôzne. Po skončení cyklu bude v oboch premenných a aj b ich najmenší spoločný deliteľ (ukončovacou podmienkou je rovnosť premenných a a b). Program, pochopiteľne, nefunguje pre záporné hodnoty.

V cykle while podobne ako v príkaze switch môžeme použiť príkaz break. V tele cyklu však tento príkaz spôsobí okamžité prerušenie vykonávania cyklu a vyskočenie programu za koniec tohto cyklu. Jedným z častých príkladov použitia je cyklus, v ktorom testujeme podmienku niekde „uprostred“:

while (true)
{
  a++;
  if (a > 100)
    break;
  b––;
}

(Nehľadajte v tomto úseku kódu hlbší zmysel, nie je tam.) Za povšimnutie stojí, že ako podmienku cyklu while sme uviedli literál true. Takáto podmienka bude vždy splnená a cyklus by sa preto nikdy neskončil, nebyť toho, že v určitom momente (v tomto prípade vtedy, keď premenná a prekročí stovku) príkazom break cyklus prerušíme.

Príkaz cyklu do

Pri príkaze while sa testuje iteračná podmienka na začiatku cyklu. Môže sa však stať, že budeme potrebovať túto podmienku testovať až na konci cyklu, pretože napríklad jej obsah závisí od toho, čo sa v tele cyklu vykonalo. Pre tento variant máme v Jave k dispozícii príkaz do s nasledujúcou syntaxou:

do
    príkaz
while ( podmienka );

Podmienka musí byť opäť typu boolean a príkaz môže byť zložený.

Pri realizácii cyklu do sa vykoná príkaz a otestuje sa hodnota podmienkového výrazu. Ak je true, cyklus sa bude opakovať, ak false, program pokračuje ďalším príkazom za cyklom do. Na rozdiel od cyklu while sa telo cyklu do vykoná vždy aspoň raz. Na predčasné opustenie tela cyklu môžeme použiť už spomínaný príkaz break.

Príklad cyklu do:

double d;
do {
  d = Math.random();
}
while (d >= 0.1);

Knižničná metóda Math.random() vracia náhodné číslo z intervalu <0; 1>. Cyklus sa teda bude opakovať, kým táto metóda nevygeneruje číslo menšie ako 0,1. Výsledkom bude náhodné oneskorenie programu (na súčasných počítačoch, samozrejme, neveľmi badateľné).

Príkaz cyklu for

Tretí príkaz cyklu, príkaz for, je značne univerzálny. Syntax má trošku zložitejšiu:

for ( init ; podmienka ; iterácia )
    príkaz

Všimnime si podrobnejšie obsah zátvorky. Skladá sa z troch častí oddelených bodkočiarkou. Prvá časť, nazvaná init, predstavuje jeden alebo viac výrazových príkazov (ak ich je viac, oddelíme ich čiarkou). Táto časť sa vykoná pred začiatkom cyklu for – môžeme povedať, že to je inicializačná časť. Dávame do nej obyčajne inicializáciu riadiacich premenných cyklu.

Druhá časť, výraz podmienka, má podobný význam ako v cykle while. Teda telo cyklu for sa bude vykonávať dovtedy, kým bude táto podmienka splnená. Len čo sa podmienka stane nepravdivou, cyklus sa končí. Podmienkový výraz sa vyhodnocuje pred telom cyklu.

Tretia časť, označená ako iterácia, obsahuje výrazy, ktoré sa majú vykonať po každom prechode cyklom. Obyčajne sa tu podľa potrieb menia riadiace premenné. Telo cyklu je tvorené príkazom, ktorý opätovne môže byť aj zložený.

Použitie príkazu for si ukážeme na úseku programu, ktorý spočíta prvých N prirodzených čísel, kde N je nejaké vopred známe číslo, uložené v premennej N:

int N = 100;
int i, sum = 0;
for (i = 1; i <= N; i++)
  sum += i;
System.out.println(sum);

Spočítavané čísla z intervalu <1; 100> uchovávame v premennej i. Táto premenná je tzv. riadiacou premennou cyklu, čo sa dá preložiť aj tak, že obsah premennej i sa vhodne mení pri každom prechode telom cyklu. Inicializačná časť príkazu for, teda príkaz i = 1, nastaví hodnotu premennej i na prvú spočítavanú hodnotu, teda na jednotku. Podmienka cyklu znie: i <= N. Cyklus sa teda bude opakovať dovtedy, kým premenná i nepresiahne koncovú hodnotu N. V tele cyklu vykonávame triviálnu operáciu, pripočítanie aktuálnej hodnoty i k premennej sum, kde uchovávame priebežný súčet. Túto premennú nesmieme zabudnúť na začiatku vynulovať. Konečne pravidelné zvyšovanie hodnoty i o jednu zabezpečí tretí výraz, i++.

Nikde nie je napísané, že riadiacu premennú cyklu musíme v tele cyklu použiť. Keby sme chceli vypísať desaťkrát hoci reťazec „Java pod lupou“ (síce neviem načo, ale ako príklad to postačí), napíšeme cyklus:

for (int i = 0; i < 10; i++)
  System.out.println("Java pod lupou");

Pozorný čitateľ si isto všimne, že v inicializačnej časti cyklu sa nachádza deklaračný príkaz int i = 0. To je dovolené, ale pozor, takto deklarovaná premenná i je lokálna pre daný cyklus a po jeho skončení zaniká. Okrem toho nesmieme v inicializácii kombinovať deklaračné a výrazové príkazy. Inak by totiž mohlo dôjsť k dvojznačnosti, napr. pri takomto cykle:

for (int i = 0, j = 10; ... )

kde sú v inicializačnej časti dva príkazy, by nebolo jasné, či druhý príkaz j = 10 priraďuje hodnotu 10 existujúcej premennej j alebo deklaruje novú premennú j typu int a nastavuje ju na hodnotu 10. Z tohto dôvodu platí pravidlo, že ak je prvý príkaz deklaračný, za deklaračné sa považujú aj ostatné.

Riadiacu premennú cyklu nemusíme nevyhnutne pri každom prechode cyklom inkrementovať. Dajme tomu, že potrebujeme vypísať mocniny dvojky od 20 po 210. Nič ľahšie:

for (int i = 1; i <= 1024; i *= 2)
  System.out.println(i);

Premenná i sa po každej iterácii cyklu zdvojnásobí pomocou výrazu i *= 2.

Ak sa zamyslíme nad spôsobom vykonávania cyklu for, dôjdeme k záveru, že ho môžeme teoreticky prepísať takýmto spôsobom:

init ;
while ( podmienka )
{
    príkaz ;
    iterácia ;
}

Tento prepis platí okrem jednej malej výnimky, o ktorej si povieme v ďalšom odseku. K príkazu for zostáva už len dodať, že ak chceme cyklus ukončiť predčasne, použijeme známy príkaz break.

Príkazy break a continue

Posledné dva príkazy, o ktorých bude reč, sú príkazy break a continue. Prvý z nich, break, sme už niekoľkokrát spomínali. Tento príkaz možno použiť buď vo vetviacom príkaze switch na okamžité vyskočenie von z bloku, alebo v príkazoch cyklu while, do a for na okamžité ukončenie cyklu. Inde jeho použitie vedie k chybe pri preklade.

Príkaz break však možno použiť aj s jedným argumentom, ktorým je tzv. návestie. O návestiach sme sa už bavili v súvislosti s príkazom switch. V Jave však môže byť každý zložený príkaz, resp. každý z príkazov switch, while, do, for, ktoré obsahujú zložený príkaz, označený pomocou návestia. Návestím je obyčajný reťazec znakov (platia rovnaké pravidlá ako pre názvy premenných) ukončený dvojbodkou, ktorý umiestnime pred príslušný zložený príkaz. Výskyt príkazu break s návestím potom spôsobí okamžité vyskočenie zo zloženého príkazu, ktorý je týmto návestím označený. Je zrejmé, že sa tento break musí v danom zloženom príkaze nachádzať.

Typicky sa príkaz break s návestím používa na vyskočenie z vnoreného cyklu, čo sa v C++ s obľubou robí pomocou príkazu goto. Tento azda najpolemizovanejší príkaz nepodmieneného skoku v Jave totiž nenájdeme. Ukážme si príklad:

outer:
for (int i = 0; i < 10; i++)
{
  for (int j = 0; j < 10; j++)
  {
    if (i == j)
      break;
    if (i == 8)
      break outer;
    System.out.print(i + "–" + j + " ");
  }
  System.out.println("");
}

 

V príklade máme dva vnorené cykly, pomocou ktorých prechádzame pomyselnú súradnicovú mriežku, súradnice máme v premenných i a j. V každom prechode vnútorným cyklom vypíšeme súradnice aktuálneho bodu mriežky na obrazovku. V prípade, že sa nachádzame na diagonále, kde sú obe súradnice rovnaké (i == j), tento a nasledujúce body na aktuálnom riadku „preskočíme“. Okrem toho, keď sa dostaneme na predposledný riadok, pre ktorý bude v i hodnota 8, vyskočíme pomocou break outer z celého cyklu, a teda body na riadkoch so súradnicami 8 a 9 vôbec nevypíšeme. Všetko bude oveľa jasnejšie po spustení programu.

Druhý príkaz, continue, sa používa iba v príkazoch cyklu, teda while, do a for. Pokiaľ ho použijeme bez návestia, spôsobí okamžité ukončenie práve prebiehajúcej iterácie cyklu a skok na pomyselný začiatok cyklu, čo spôsobí nové vyhodnotenie cyklovacej podmienky a podľa jej výsledku prípadné pokračovanie či nepokračovanie v cykle. V príkaze for sa pred týmto opätovným testovaním podmienky ešte vykonajú všetky výrazy tretej, iteračnej časti (pozri vyššie). To je ten spomínaný malý rozdiel medzi for a jeho náhradou pomocou while.

Aj príkaz continue možno použiť s návestím, význam je analogický: ukončí sa práve prebiehajúca iterácia toho cyklu, ku ktorému dané návestie patrí. Modifikujme predchádzajúci príklad tak, že príkazy break nahradíme príkazmi continue:

outer:
for (int i = 0; i < 10; i++)
{
  for (int j = 0; j < 10; j++)
  {
    if (i == j)
      continue;
    if (i == 8)
      continue outer;
    System.out.print(i + "–" + j + " ");
  }
  System.out.println("");
}

Tentoraz sa z výpisu vynechajú iba body ležiace na diagonále a celý riadok so súradnicou 8.

Prázdny príkaz

Príkazov v Jave nájdeme ešte o niečo viac, ale tie sa vzťahujú buď na výnimky (try, finally, catch, throw), alebo na synchronizáciu v multithreadovom prostredí (synchronized), takže si o nich povieme až neskôr. Na záver sa patrí spomenúť tzv. prázdny príkaz, ktorým je jednoducho „nič“ nasledované bodkočiarkou:

;

Prázdny príkaz možno použiť napríklad ako telo cyklu for, ktorého celú náplň sme vyjadrili buď v podmienkovom, alebo v iteračnom výraze.

 

 

 

 


Nechajte si posielať prehľad najdôležitejších správ emailom

Mohlo by Vás zaujímať

Ako na to

Ako funguje sandbox?

08.12.2016 15:36

Každá aplikácia môže pre operačný systém počítača či mobilného zariadenia predstavovať potenciálnu hrozbu, a to aj v prípade, ak neobsahuje žiadne bloky škodlivého kódu. Murphyho zákony neúprosne defi ...

Ako na to

Tipy a triky: Ako na snímku obrazovky na akomkoľvek počítači s Windows?

02.12.2016 00:13

Ak snímky obrazovky robíte často apotrebujete napríklad funkcie na posun stránok alebo snímanie zobrazenia pri vyššom rozlíšení displeja, zrejme používate nejakú špecializovanú aplikáciu. Väčšina použ ...

Ako na to 1

Tipy a triky: Ako aplikácii prednastaviť spúšťanie s administrátorskými právami?

30.11.2016 00:10

Väčšina aspoň trochu skúsenejších používateľov vie, že aj keď máte na operačnom systéme Windows vytvorený administrátorský účet, aplikácie pre bezpečnosť nefungujú vždy splnými administrátorskými práv ...

Žiadne komentáre

Vyhľadávanie

Kyocera - prve-zariadenia-formatu-a4-s-vykonom-a3

Najnovšie videá