12. diel - Cykly v C # .NET druhýkrát - do-while, break a continue
V minulej lekcii, Podmienky v C # druhýkrát - ternárne výraz a propadávací switch , sme sa venovali ďalšie syntax podmienok.
Na úvod by bolo dobré podotknúť, že dnešná lekcia obsahuje menej používané praktiky a slúži hlavne na to, aby vás neprekvapili v cudzom kódu. Nie je príliš dôležité, aby ste ich sami vedeli používať.
do
... while
Cyklus while
už dobre poznáme. Menej používaný
do
... while
sa odlišuje len tým, že sa vždy
vykoná najmenej raz. Jeho podmienka je totiž umiestnená až za telom
cyklu. Vyzerá teda takto:
do { // kód... } while (podmienka)
Aj na zapísanie tohto cyklu môžeme využiť snippet vo
Visual Studio: Napíšeme do
a dvakrát prechádzať
pomocou tabulátora. Zvyšok cyklu sa sám dopíše.
Príklad
Použitie do
- while
cyklu si ukážme na našej
kalkulačke z lekcie o
cykloch. Pre skrátenie príkladu nebudeme používať verziu s overením
užívateľských vstupov.
Variant s while
V kalkulačke sme použili cyklus while
, ktorý umožnil celý
program opakovať a tak zadávať ďalšie a ďalšie príklady. Kód vyzeral
takto (jedná sa o verziu s konštrukciou switch
):
Console.WriteLine("Vitajte v kalkulačke"); string pokracovat = "áno"; while (pokracovat == "áno") { Console.WriteLine("Zadajte prvé číslo:"); float a = float.Parse(Console.ReadLine()); Console.WriteLine("Zadajte druhé číslo:"); float b = float.Parse(Console.ReadLine()); Console.WriteLine("Zvoľte si operáciu:"); Console.WriteLine("1 - sčítanie"); Console.WriteLine("2 - odčítanie"); Console.WriteLine("3 - násobenie"); Console.WriteLine("4 - delenie"); int volba = int.Parse(Console.ReadLine()); 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)) Console.WriteLine("Výsledok: {0}", vysledek); else Console.WriteLine("Neplatná voľba"); Console.WriteLine("Prajete si zadať ďalší príklad? [áno/nie]"); pokracovat = Console.ReadLine(); } Console.WriteLine("Ďakujem za použitia kalkulačky, aplikáciu ukončíte ľubovoľnou klávesou."); Console.ReadKey();
Všimnite si, že sme sa pri tejto variante s while
museli
zamyslieť nad východiskovou hodnotou premennej pokracovat
, ktoré
sme nastavili hodnotu "ano"
, aby podmienka bola splnená pre prvý
priechod cyklom. Vymyslieť predvolenú hodnotu môže byť ale niekedy pomerne
zložité a trebárs aj vyžadovať pomocnú premennú.
Variant s do
- while
Keď použijeme cyklus do
- while
, tak predvolenú
hodnotu danej premennej nemusíme riešiť:
Console.WriteLine("Vitajte v kalkulačke"); string pokracovat; do { Console.WriteLine("Zadajte prvé číslo:"); float a = float.Parse(Console.ReadLine()); Console.WriteLine("Zadajte druhé číslo:"); float b = float.Parse(Console.ReadLine()); Console.WriteLine("Zvoľte si operáciu:"); Console.WriteLine("1 - sčítanie"); Console.WriteLine("2 - odčítanie"); Console.WriteLine("3 - násobenie"); Console.WriteLine("4 - delenie"); int volba = int.Parse(Console.ReadLine()); 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)) Console.WriteLine("Výsledok: {0}", vysledek); else Console.WriteLine("Neplatná voľba"); Console.WriteLine("Prajete si zadať ďalší príklad? [áno/nie]"); pokracovat = Console.ReadLine(); } while (pokracovat == "áno"); Console.WriteLine("Ďakujem za použitia kalkulačky, aplikáciu ukončíte ľubovoľnou klávesou."); Console.ReadKey();
break
a continue
Beh cyklu je potreba niekedy prerušiť, k tomu máme nasledujúce 2 kľúčové slová.
break
Príkaz break
ukončuje aktuálny cyklus. Používa sa
najčastejšie ak pomocou cyklu nájdeme nejakú položku v kolekcii a ďalej
už v jej prehliadaní nechceme pokračovať. Nebudeme tak ďalej
zbytočne prehľadávať zvyšok kolekcie, keď už máme to, čo sme
hľadali.
Príklad
Predstavme si, že máme pole položiek a chceme v nich nejakú nájsť. Že
môžeme použiť metódu IndexOf()
alebo Contains()
?
Pokiaľ pôjde o pole, tak áno, ale niektoré kolekcie ju nemajú a / alebo
chceme hľadať pomocou nejakej iné vlastnosti, než ktorú tieto metódy
zohľadňujú. Potom si vyhľadávanie musíme napísať pekne ručne cyklom
alebo použiť výrazne pokročilejšie konštrukcie, ako teraz ovládame.
Predstavme si, že máme veľké a malé štítky na poháre a chceme použiť na všetky poháre buď jedny alebo druhé. Zaujíma nás teda, či sa text všetkých popisok zmestí na malé štítky. Napíšeme program, ktorý zistí, či je v poli slovo dlhšie ako 6 znakov. Ak áno, musíme použiť väčšie štítky.
Začneme cyklom prechádzať jednotlivé slová a akonáhle nájdeme slovo
dlhšie ako 6 znakov, tak si uložíme jeho index. Zatiaľ stále nič nové pod
slnkom. V tú istú chvíľu však pomocou break
cyklus
ukončíme.
Ukážka použitia break
:
string[] seznamOvoce = {"Jablka", "Hrušky", "Švestky", "Meruňky", "Jahody", "Třešně"}; int hledanyIndex = -1; for (int i = 0; i < seznamOvoce.Length; i++) { if (seznamOvoce[i].Length > 6) { hledanyIndex = i; break; } } if (hledanyIndex >= 0) Console.WriteLine("Prvé slovo dlhšie ako 6 znakov: " + seznamOvoce[hledanyIndex]);
výstup:
Konzolová aplikácia
Prvé slovo dlhšie ako 6 znakov: Švestky
Príkaz break
sa v praxi často nahrádza príkazom
return
za predpokladu, že je kód v našej vlastnej metóde.
Vlastné metódy sa ale naučíme deklarovať až v nadväzujúcom kurze Základy objektovo orientovaného programovania v C#.
Potom break
odporúčam skôr nepoužívať, správnejšie varianta
je kód pre prácu s kolekciou vyčleniť do samostatnej funkcie.
continue
Príkaz continue
je podobný break
. Používa sa
však k ukončeniu iba aktuálnej iterácie (priebehu) cyklu a nie
celého cyklu. Cyklus potom rovno prechádza na ďalšiu iteráciu.
Použitie continue
môžeme nájsť napr. Pri validovanie
položiek pri prehliadaní nejakej kolekcie.
Príklad
Predstavme si, že máme od užívateľa zadané čísla a tieto čísla chceme sčítať. Užívateľ tieto čísla zadá ako jeden reťazec, kde každé číslo je oddelené čiarkou. Bohužiaľ musíme počítať aj s tým, že používateľ zadá namiesto čísla nejaký nezmysel. Riešenie by mohlo vyzerať nasledovne:
string cislaRetezec = "10,50,abcd,30,9"; // rozloženie reťazca do poľa string[] cislaPole = cislaRetezec.Split(','); int soucet = 0; foreach (string cislo in cislaPole) { // prevedenie reťazca na celé číslo int celeCislo; if(!int.TryParse(cislo, out celeCislo)) continue; soucet += celeCislo; } Console.WriteLine("Súčet je: " + soucet);
výstup:
Konzolová aplikácia
Súčet je: 99
Program spočíta všetky správne zadané hodnoty, teda tie, u ktorých
metóda TryParse()
vrátila hodnotu true
. U nesprávne
zadaných hodnôt je aktuálna iterácie ukončená. Namiesto
continue
by sme samozrejme mohli použiť len príkaz
if
, kód by sme tým však zbytočne zaboril.
Skrátený zápis cyklu for
Nasledujúce konštrukcie sú tu pre ukážku čo všetko je možné stretnúť v cudzích kódoch a nie je dobrý dôvod ich používať!
Cyklus for
je možné zapísať takto skrátene, bez tela
cyklu:
for (int i = 0; i < 10; Console.Write(i++));
výstup:
Konzolová aplikácia
0123456789
Písať logiku priebehu behu cyklu aj logiku v cykle na jeden riadok však nie je intuitívne. Navyše sa tak môže ľahko zabudnúť na inkrementácia premenné alebo ju inkrementovať viackrát.
Dokonca nie je nutné v hlavičke cykle for
uvádzať
akýkoľvek príkaz:
for (;;) { // nekonečný cyklus }
Tento zápis je rovnaký ako:
while (true) { // nekonečný cyklus }
Oba vyššie deklarované cykly beží do nekonečna a môžete ich
stretnúť v zle napísaných zdrojových kódoch spolu s príkazmi
break
, ktoré z nich potom za nejakých podmienok vyskakujú.
Akonáhle podmienka nie je priamo v deklarácii cykle, je pomerne neprehľadné zistiť kedy cyklus vôbec skončí a ľahké urobiť z takéhoto cyklu nechtiac nekonečný. To platí obzvlášť, keď z cyklu vyskakuje viac podmienkami a neskrývane všetky možné prípady.
Hoci dnešné lekcie obsahovala štandardnú gramatiku C# .NET
pre cykly, z nových konštrukcií používajte iba do
-
while
a continue
. Prechodne ešte môžete používať
break
, než sa dostaneme k objektom:)