NOVINKA: Kurz kybernetické bezpečnosti s akreditací MŠMT, nyní již od 0 Kč. Staň se žádaným profesionálem. Zjisti více:
NOVINKA: Staň se datovým analytikem a získej jistotu práce, lepší plat a nové kariérní možnosti. Více informací:

Lekce 13 - Podmínky v C# podruhé - Ternární výraz a propadávací switch

V předešlém cvičení, Řešené úlohy k 12. lekci C# .NET, jsme si procvičili nabyté zkušenosti z předchozích lekcí.

V dnešní lekci si představíme dvě další konstrukce, které souvisejí s podmínkami. Jedná se o oddechový tutoriál, kterým toto téma dokončíme.

Ternární výraz

Často se nám stává, že někde potřebujeme nastavit dvě různé hodnoty podle toho, zda platí nějaká podmínka.

Příklad – Výpis pohlaví

Představme si, že máme např. pohlaví uživatele uložené jako bool (muž by byl true) a chceme ho převést do textu. S dosavadními znalostmi bychom napsali asi takovýto kód:

bool muz = true; // nějaká proměnná udávající pohlaví
string nazevPohlavi;
if (muz)
    nazevPohlavi = "muž";
else
    nazevPohlavi = "žena";
Console.WriteLine(nazevPohlavi);

Výstup programu je samozřejmě následující:

Konzolová aplikace
muž

Ačkoli kód pouze přepíná mezi dvěma hodnotami, je poměrně rozsáhlý. Proto programovací jazyky často podporují tzv. ternární výraz.

Syntaxe ternárního výrazu

Pomocí operátorů ? a : můžeme získat hodnotu podle platnosti logického výrazu. Zapíšeme jej takto:

(vyraz) ? hodnota1 : hodnota2

Podmínku vložíme většinou do závorky (), poté následuje otazník ? a dvě hodnoty, které se mají vrátit. Hodnoty jsou oddělené dvojtečkou :. První hodnota se vrátí, pokud podmínka platí, druhá hodnota se vrátí naopak v případě neplatnosti podmínky. Jak snadné! :) Název výrazu je odvozený od toho, že se skládá ze tří částí (z podmínky, první hodnoty a druhé hodnoty), proto ternární.

Příklad – Použití ternárního výrazu

Pojďme si ternární výraz vyzkoušet na příkladu s pohlavím:

bool muz = true; // nějaká proměnná udávající pohlaví
string nazevPohlavi = (muz) ? "muž" : "žena";
Console.WriteLine(nazevPohlavi);

Místo typu bool bychom mohli do závorky samozřejmě napsat jakoukoli jinou podmínku, např. (vek >= 18) ? "zletilý" : "nezletilý". V případě jednoduchých výrazů můžeme závorku i vynechat.

Vnořování ternárních výrazů

Ternární výrazy teoreticky lze vnořovat do sebe a tím reagovat i na tři a více hodnot. Nicméně ve většině případů vnořování spíše kód znepřehlední. Vznikají totiž dlouhé nebo podivně zalomené řádky a není na první pohled vidět, která část se kdy spustí. Ukažme si, jak by se pomocí vnořování ternárních výrazů vyřešil výpis tří smajlíků:

string smajlik = ":)"; // nějaká proměnná udávající smajlíka
string nalada = (smajlik == ":)") ? "veselý" : (smajlik == ":(") ? "smutný" : "neznámý";
Console.WriteLine(nalada);

Pro příklad výše by bylo lepší vytvořit vlastní metodu, což si ale ukážeme až v navazujícím kurzu objektově orientovaného programování.

switch s propadáváním

S konstrukcí switch jsme se již setkali v lekci Podmínky (větvení). Dnes si ukážeme její další použití. Na rozdíl od ternárního výrazu jde ale spíše o historickou funkčnost, pro kterou dnes není moc rozumných využití. Konstrukce switch je však stále součástí standardní gramatiky C# .NET a můžeme na ni narazit v cizích zdrojových kódech.

Příklad – Čtvrtletí

Předpokládejme, že chceme podle měsíce v roce zjistit, které je čtvrtletí. Pomocí if a else by příklad vypadal následovně:

int mesic = 2;
if (mesic >= 1 && mesic <= 3)
    Console.WriteLine("Je první čtvrtletí.");
else if (mesic >= 4 && mesic <= 6)
    Console.WriteLine("Je druhé čtvrtletí.");
else if (mesic >= 7 && mesic <= 9)
    Console.WriteLine("Je třetí čtvrtletí.");
else if (mesic >= 10 && mesic <= 12)
    Console.WriteLine("Je čtvrté čtvrtletí.");

Jak ale použít switch pro takovýto příklad? Možná by vás napadl následující zápis:

int mesic = 11;
switch (mesic)
{
    case 1:
        Console.WriteLine("Je první čtvrtletí.");
        break;
    case 2:
        Console.WriteLine("Je první čtvrtletí.");
        break;
    case 3:
        Console.WriteLine("Je první čtvrtletí.");
        break;
    case 4:
        Console.WriteLine("Je druhé čtvrtletí.");
        break;
    case 5:
        Console.WriteLine("Je druhé čtvrtletí.");
        break;
    case 6:
        Console.WriteLine("Je druhé čtvrtletí.");
        break;
    case 7:
        Console.WriteLine("Je třetí čtvrtletí.");
        break;
    case 8:
        Console.WriteLine("Je třetí čtvrtletí.");
        break;
    case 9:
        Console.WriteLine("Je třetí čtvrtletí.");
        break;
    case 10:
        Console.WriteLine("Je čtvrté čtvrtletí.");
        break;
    case 11:
        Console.WriteLine("Je čtvrté čtvrtletí.");
        break;
    case 12:
        Console.WriteLine("Je čtvrté čtvrtletí.");
        break;
}

Příklad funguje spolehlivě, problém však je, že jsme si tímto zápisem moc nepomohli. Podobnému repetitivnímu kódu bychom se vždy měli vyhýbat.

Propadávání

Zkusme to ještě jednou a využijme tzv. propadávání. Potřebujeme-li ve více blocích case provádět stejný kód, stačí tyto bloky vložit pod sebe a pomocí break ukončit celou skupinu bloků najednou, nikoli každý blok zvlášť. Neukončené bloky tak propadnou a vykoná se kód společný pro více bloků:

int mesic = 11;
switch (mesic)
{
    case 1:
    case 2:
    case 3:
        Console.WriteLine("Je první čtvrtletí.");
        break;
    case 4:
    case 5:
    case 6:
        Console.WriteLine("Je druhé čtvrtletí.");
        break;
    case 7:
    case 8:
    case 9:
        Console.WriteLine("Je třetí čtvrtletí.");
        break;
    case 10:
    case 11:
    case 12:
        Console.WriteLine("Je čtvrté čtvrtletí.");
        break;
}

Ukázka výstupu aplikace:

Konzolová aplikace
Je čtvrté čtvrtletí.

Tento zápis je již mnohem přehlednější. Konstrukce switch má ovšem přidanou hodnotu hlavně v případě, kdy nemůžeme použít větší/menší a jde o výčet hodnot. V našem případě jde spíše o redundantní kód plný prázdných case.

C# podporuje propadávání pouze v případě prázdných case. Můžete si zkusit, že jakmile case obsahují nějaký kód, ten se bez break nepřeloží. I z neprázdných case lze teoreticky propadávat do dalších pomocí příkazu goto case hodnota;, jedná se ale o špatnou a matoucí praktiku, proto ji nepoužívejte!

Propadávání používejte v konstrukci switch pouze tehdy, máte-li k němu dobrý důvod. Je však důležité, abyste jej uměli číst, když na něj někde narazíte.

Shrnutí lekce

Ternární výraz slouží k rychlému výběru jedné ze dvou hodnot podle podmínky, takže se hodí hlavně tam, kde bychom jinak psali krátké if a else. Ternární výrazy je možné také vnořovat, ale tím se kód často stává hůře čitelným.

U příkazu switch jsme si ukázali propadávání, tedy možnost spojit více větví case, které mají provést stejnou akci. To se hodí například při zařazení několika měsíců do stejného čtvrtletí. Je dobré vědět, jak propadávání funguje, protože se s ním můžeme setkat v cizím kódu. Používat bychom ho ale měli jen tehdy, když zápis opravdu zpřehlední.

V příští lekci, Cykly v C# .NET podruhé - do-while, break a continue, na nás čeká další syntaxe týkající se cyklů, na kterou můžeme narazit v cizích zdrojových kódech.


 

Předchozí článek
Řešené úlohy k 12. lekci C# .NET
Všechny články v sekci
Základní konstrukce jazyka C# .NET
Přeskočit článek
(nedoporučujeme)
Cykly v C# .NET podruhé - do-while, break a continue
Článek pro vás napsal Radek Vymětalík
Avatar
Uživatelské hodnocení:
678 hlasů
...
Aktivity