Office week BF - Easter
Tento týden až 80% sleva na e-learning MS Office!
80 % bodů zdarma díky naší Velikonoční akci!

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

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

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

Ternární operátor

Často se nám stává, že někde potřebujeme nastavit 2 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 my bychom ho chtěli 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ž

Kód je poměrně upovídaný na to, že jen přepíná mezi dvěma hodnotami. Proto programovací jazyky často podporují tzv. ternární výraz.

Syntaxe ternárního výrazu

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

(vyraz) ? hodnota1 : hodnota2
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Podmínku vložíme většinou do závorky (), poté následuje otazník ? a 2 hodnoty, které se mají vrátit. Hodnoty jsou oddělené dvojtečkou :, první se vrátí když podmínka platí a druhá když neplatí. Jak snadné! :) Název operátoru je odvozený od toho, že má 3 části (podmínka, první hodnota a druhá hodnota), proto ternární.

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

Pojďme si ternární operátor 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 operátorů

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

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

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 operátoru jde ale spíše o historickou funkčnost, pro kterou dnes není moc rozumných využití. Stále je ale součástí standardní gramatiky C# .NET a můžete 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, jaké 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í. Pokud potřebujeme ve více blocích case provádět stejný kód, stačí tyto bloky vložit pod sebe a neukončovat každý blok pomocí break, ale celou skupinu bloku jedním break. 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 v případě, kdy nemůžeme použít větší/menší a jde o výčet hodnot, zde je to spíše redundantní kód plný prázdných case.

C# podporuje propadávání pouze v prázdných case. Můžete si zkusit, že jakmile obsahují nějaký kód, kód 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 ve switch jen pokud k němu máte dobrý důvod, nicméně je 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 okolo cyklů, na kterou můžeme narazit v cizích zdrojových kódech.


 

 

Aktivity (3)

 

 

Komentáře

Avatar
Honza
Člen
Avatar
Honza:9. března 16:28

Děkuju za článek.
Vrtá mi ale hlavou jedna věc: proč C# neumožňuje nějak přehledně řešit podmínku pro intervaly hodnot. Něco na tento způsob:

switch (procenta) {
  case 1..50: break;
  case 51..80: break;
  case 81..90: break;
  case 91..95: break;
  case 96..98: break;
  case 99: break;
  case 100: break;
  default: break;
}

Vím že je to spíš filosofická otázka, protože to c# prostě neumožňuje. Ale stejně by mě to zajímalo - např. často zatracovaný Visual Basic tuto konstrukci evidentně umožňuje a přitom oba jazyky jsou postaveny na tom samém základu - .NET

 
Odpovědět
9. března 16:28
Avatar
David Holohlavský:19. března 19:00

Díky za článek. ;-)

 
Odpovědět
19. března 19:00
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Fíla N.
Člen
Avatar
Fíla N.:29. března 17:40

Hej, kde se to tu vzalo, to tu nebylo :D , ale díky

 
Odpovědět
29. března 17:40
Avatar
Marek Vajčner:30. března 9:39

Díky za oddechovku. ;-)

 
Odpovědět
30. března 9:39
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 4 zpráv z 4.