Lekce 12 - Podmínky v C# podruhé - Ternární výraz a propadávací switch
V předešlém cvičení, Řešené úlohy k 11. 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:
{CSHARP_CONSOLE}
bool muz = true; // nějaká proměnná udávající pohlaví
string nazevPohlavi;
if (muz)
nazevPohlavi = "muž";
else
nazevPohlavi = "žena";
Console.WriteLine(nazevPohlavi);
{/CSHARP_CONSOLE}
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:
{CSHARP_CONSOLE}
bool muz = true; // nějaká proměnná udávající pohlaví
string nazevPohlavi = (muz) ? "muž" : "žena";
Console.WriteLine(nazevPohlavi);
{/CSHARP_CONSOLE}
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ů:
{CSHARP_CONSOLE}
string smajlik = ":)"; // nějaká proměnná udávající smajlíka
string nalada = (smajlik == ":)") ? "veselý" : (smajlik == ":(") ? "smutný" : "neznámý";
Console.WriteLine(nalada);
{/CSHARP_CONSOLE}
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ě:
{CSHARP_CONSOLE}
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í.");
{/CSHARP_CONSOLE}
Jak ale použít switch
pro takovýto příklad? Možná by vás
napadl následující zápis:
{CSHARP_CONSOLE}
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;
}
{/CSHARP_CONSOLE}
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ů:
{CSHARP_CONSOLE}
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;
}
{/CSHARP_CONSOLE}
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.
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.