NOVINKA! E-learningové kurzy umělé inteligence. Nyní AI za nejlepší ceny. Zjisti více:
NOVINKA – Víkendový online kurz Software tester, který tě posune dál. Zjisti, jak na to!

Lekce 13 - Cykly v C# .NET podruhé - do-while, break a continue

V minulé lekci, Podmínky v C# podruhé - Ternární výraz a propadávací switch, jsme se věnovali další syntaxi podmínek.

Na úvod by bylo dobré podotknout, že dnešní lekce obsahuje méně používané praktiky a slouží hlavně k tomu, aby nás tyto praktiky nepřekvapily v cizím kódu. Není příliš důležité, abychom je sami uměli používat.

do-while

Cyklus while již dobře známe. Méně používaný do-while se liší pouze tím, že se vždy vykoná nejméně jednou. Podmínka tohoto cyklu je totiž umístěna až za jeho tělem. Vypadá tedy takto:

do
{
    // kód...
} while (podmínka);

I k zapsání tohoto cyklu můžeme využít snippet ve Visual Studiu: Napíšeme do a dvakrát stiskneme Tabulátor. Zbytek cyklu se sám dopíše.

Příklad

Použití do-while cyklu si ukažme na naší kalkulačce z lekce o cyklech. Pro zkrácení příkladu nebudeme používat verzi s ověřením uživatelských vstupů.

Varianta s cyklem while

V kalkulačce jsme použili cyklus while, který umožnil celý program opakovat, a tak zadávat další a další příklady. Kód vypadal takto (jedná se o verzi s konstrukcí switch):

Console.WriteLine("Vítejte v kalkulačce");
string pokracovat = "ano";
while (pokracovat == "ano")
{
    Console.WriteLine("Zadejte první číslo:");
    float a = float.Parse(Console.ReadLine());
    Console.WriteLine("Zadejte druhé číslo:");
    float b = float.Parse(Console.ReadLine());
    Console.WriteLine("Zvolte si operaci:");
    Console.WriteLine("1 - sčítání");
    Console.WriteLine("2 - odčítání");
    Console.WriteLine("3 - násobení");
    Console.WriteLine("4 - dělení");
    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ýsledek: {0}", vysledek);
    else
        Console.WriteLine("Neplatná volba");
    Console.WriteLine("Přejete si zadat další příklad? [ano/ne]");
    pokracovat = Console.ReadLine();
}
Console.WriteLine("Děkuji za použití kalkulačky, aplikaci ukončíte libovolnou klávesou.");
Console.ReadKey();

Všimněme si, že jsme se u této varianty s while museli zamyslet nad výchozí hodnotou proměnné pokracovat. Té jsme nastavili hodnotu "ano", aby podmínka byla splněna pro první průchod cyklem. Vymyslet výchozí hodnotu ale může být poměrně složité a někdy je třeba použít i pomocnou proměnnou.

Varianta s cyklem do-while

Když použijeme cyklus do-while, výchozí hodnotu dané proměnné už nemusíme řešit:

Console.WriteLine("Vítejte v kalkulačce");
string pokracovat;
do
{
    Console.WriteLine("Zadejte první číslo:");
    float a = float.Parse(Console.ReadLine());
    Console.WriteLine("Zadejte druhé číslo:");
    float b = float.Parse(Console.ReadLine());
    Console.WriteLine("Zvolte si operaci:");
    Console.WriteLine("1 - sčítání");
    Console.WriteLine("2 - odčítání");
    Console.WriteLine("3 - násobení");
    Console.WriteLine("4 - dělení");
    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ýsledek: {0}", vysledek);
    else
        Console.WriteLine("Neplatná volba");
    Console.WriteLine("Přejete si zadat další příklad? [ano/ne]");
    pokracovat = Console.ReadLine();
} while (pokracovat == "ano");

Console.WriteLine("Děkuji za použití kalkulačky, aplikaci ukončíte libovolnou klávesou.");
Console.ReadKey();

break a continue

Někdy je potřeba běh cyklu přerušit. K tomu nám slouží následující dvě klíčová slova.

break

Příkaz break ukončuje aktuální cyklus. Používá se nejčastěji tehdy, když pomocí cyklu nalezneme nějakou položku v kolekci a dále již v jejím procházení nechceme pokračovat. Nebudeme tak dále zbytečně prohledávat zbytek kolekce, neboť již máme to, co jsme hledali.

Příklad

Představme si, že máme pole položek a chceme v nich nějakou najít. Nabízí se použít metodu IndexOf() nebo Contains(). Pokud půjde o pole, bude použití těchto metod vhodné, ale některé kolekce je nemají nebo například chceme hledat pomocí jiné vlastnosti, než kterou tyto metody zohledňují. Vyhledávání pak tedy musíme buď napsat hezky ručně cyklem, nebo k němu použít výrazně pokročilejší konstrukce, než nyní ovládáme.

Představme si, že máme velké a malé štítky na sklenice. Na všechny sklenice chceme použít buď jedny, nebo druhé štítky. Zajímá nás tedy, zda se text všech popisků vejde na malé štítky. Napíšeme program, který zjistí, zda se v poli nachází slovo delší než 6 znaků. Pokud ano, musíme použít větší štítky.

Cyklem začneme procházet jednotlivá slova, a jakmile najdeme slovo delší než 6 znaků, uložíme si jeho index. Zatím stále nic nového pod sluncem. V téže chvíli však cyklus pomocí příkazu break ukončíme.

Ukázka použití příkazu 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("První slovo delší než 6 znaků: " + seznamOvoce[hledanyIndex]);

Výstup:

Konzolová aplikace
První slovo delší než 6 znaků: Švestky

Příkaz break se v praxi často nahrazuje příkazem return za předpokladu, že je kód v naší vlastní metodě. Vlastní metody se ale naučíme deklarovat až v navazujícím kurzu Základy objektově orientovaného programování v C#. Příkaz break poté doporučujeme spíše nepoužívat, správnější varianta je kód pro práci s kolekcí vyčlenit do samostatné funkce.

continue

Příkaz continue je podobný jako break. Používá se však k ukončení pouze aktuální iterace (průběhu) cyklu, a ne celého cyklu. Cyklus poté rovnou přechází na další iteraci. Na použití příkazu continue můžeme narazit např. při validování položek při procházení nějaké kolekce.

Příklad

Představme si, že máme od uživatele zadaná čísla a tato čísla chceme sečíst. Uživatel tato čísla zadá jako jeden řetězec, v němž je každé číslo oddělené čárkou. Bohužel musíme počítat i s tím, že uživatel místo čísla zadá nějaký nesmysl. Řešení by mohlo vypadat následovně:

string cislaRetezec = "10,50,abcd,30,9";
// rozložení řetězce do pole
string[] cislaPole = cislaRetezec.Split(',');
int soucet = 0;
foreach (string cislo in cislaPole)
{
    // převedení řetězce na celé číslo
    int celeCislo;

    if(!int.TryParse(cislo, out celeCislo))
        continue;

    soucet += celeCislo;
}
Console.WriteLine("Součet je: " + soucet);

Výstup:

Konzolová aplikace
Součet je: 99

Program sečte všechny správně zadané hodnoty, tedy ty, u kterých metoda TryParse() vrátila hodnotu true. U nesprávně zadaných hodnot je aktuální iterace ukončena. Místo continue bychom samozřejmě mohli použít i příkaz if, kód bychom tím však zbytečně vnořili.

Zkrácený zápis cyklu for

Následující konstrukce zde uvádíme pouze pro ukázku, s čím vším je možné se setkat v cizích kódech, a není dobrý nápad je používat!

Cyklus for je možné zapsat takto zkráceně, bez těla cyklu:

for (int i = 0; i < 10; Console.Write(i++));

Výstup:

Konzolová aplikace
0123456789

Psát logiku průběhu běhu cyklu i logiku v cyklu na jeden řádek ale není intuitivní. Navíc se tak může snadno zapomenout na inkrementaci proměnné, případně ji můžeme inkrementovat vícekrát. 

V hlavičce cyklu for dokonce není nutné uvádět jakýkoliv příkaz:

for (;;)
{
    // nekonečný cyklus
}

Tento zápis je stejný jako:

while (true)
{
    // nekonečný cyklus
}

Oba výše deklarované cykly běží donekonečna a můžete se s nimi setkat ve špatně napsaných zdrojových kódech spolu s příkazy break, které z nich potom za nějakých podmínek vyskakují.

Jakmile podmínka není přímo v deklaraci cyklu, je poměrně obtížné zjistit, kdy cyklus vůbec skončí. Z takového cyklu je pak snadné vytvořit nechtěně nekonečný. To platí zvláště tehdy, když z cyklu vyskakujeme vícero podmínkami a nepokryjeme všechny možné případy.

Ač dnešní lekce obsahovala standardní gramatiku C# .NET pro cykly, z nových konstrukcí používejte pouze do-while a continue. Přechodně ještě můžete používat break, než se dostaneme k objektům :)

V následujícím kvízu, Kvíz - Pokročilé podmínky a cykly v C# .NET, si vyzkoušíme nabyté zkušenosti z předchozích lekcí.


 

Předchozí článek
Podmínky v C# podruhé - Ternární výraz a propadávací switch
Všechny články v sekci
Základní konstrukce jazyka C# .NET
Přeskočit článek
(nedoporučujeme)
Kvíz - Pokročilé podmínky a cykly v C# .NET
Článek pro vás napsal Radek Vymětalík
Avatar
Uživatelské hodnocení:
570 hlasů
...
Aktivity