C týden
Tento týden až 80% sleva na e-learning týkající se jazyka C
50 % bodů zdarma na online výuku díky naší Slevové akci!

Lekce 5 - Podmínky (větvení) v C# .NET

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

Abychom si něco naprogramovali, potřebujeme nějak reagovat na různé situace. Může to být například hodnota zadaná uživatelem, podle které budeme chtít měnit další běh programu. Říkáme, že se program větví a k větvení používáme podmínky, těm se budeme věnovat celý dnešní C# tutoriál. Vytvoříme program na výpočet odmocniny a vylepšíme naši kalkulačku.

Podmínky

V C# se podmínky píší úplně stejně, jako ve všech CLike jazycích, pro začátečníky samozřejmě vysvětlím. Pokročilejší se asi budou chvilku nudit :)

Podmínky zapisujeme pomocí klíčového slova if, za kterým následuje logický výraz. Pokud je výraz pravdivý, provede se následující příkaz. Pokud ne, následující příkaz se přeskočí a pokračuje se až pod ním.

V následující ukázce použijeme znaky větší > a menší <. Pokud nevíte, kde je na české klávesnici najít, píšeme je pomocí Pravého Alt a následujících kláves:

Větší než; menší než na české klávesnici

Vyzkoušejme si to:

if (15 > 5)
    Console.WriteLine("Pravda");
Console.WriteLine("Program zde pokračuje dál");
Console.ReadKey();

Výstup programu:

Konzolová aplikace
Pravda
Program zde pokračuje dál

Pokud podmínka platí (což zde ano), provede se příkaz vypisující do konzole text pravda. V obou případech program pokračuje dál. Součástí výrazu samozřejmě může být i proměnná:

Console.WriteLine("Zadej nějaké číslo");
int a = int.Parse(Console.ReadLine());
if (a > 5)
    Console.WriteLine("Zadal jsi číslo větší než 5!");
Console.WriteLine("Děkuji za zadání");
Console.ReadKey();

Ukažme si nyní relační operátory, které můžeme ve výrazech používat:

Operátor C-like Zápis
Rovnost ==
Je ostře větší >
Je ostře menší <
Je větší nebo rovno >=
Je menší nebo rovno <=
Nerovnost !=
Obecná negace !
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Rovnost zapisujeme dvěma == proto, aby se to nepletlo s běžným přiřazením do proměnné, které se dělá jen jedním =. Pokud chceme nějaký výraz znegovat, napíšeme ho do závorky a před něj vykřičník. Když budeme chtít vykonat více než jen jeden příkaz, musíme příkazy vložit do bloku ze složených závorek:

Console.WriteLine("Zadej nějaké číslo, ze kterého spočítám odmocninu:");
int a = int.Parse(Console.ReadLine());
if (a > 0)
{
    Console.WriteLine("Zadal jsi číslo větší než 0, to znamená, že ho mohu odmocnit!");
    double o = Math.Sqrt(a);
    Console.WriteLine("Odmocnina z čísla " + a + " je " + o);
}
Console.WriteLine("Děkuji za zadání");
Console.ReadKey();

Konzolová aplikace
Zadej nějaké číslo, ze kterého spočítám odmocninu:
144
Zadal jsi číslo větší než 0, to znamená, že ho mohu odmocnit!
Odmocnina z čísla 144 je 12
Děkuji za zadání

Program načte od uživatele číslo a pokud je větší než 0, vypočítá z něj druhou odmocninu. Mimo jiné jsme použili třídu Math, která na sobě obsahuje řadu užitečných matematických metod, na konci této kapitoly si ji blíže představíme. Sqrt() vrací druhou odmocninu jako double. Bylo by hezké, kdyby nám program vyhuboval v případě, že zadáme záporné číslo. S dosavadními znalostmi bychom napsali něco jako:

Console.WriteLine("Zadej nějaké číslo, ze kterého spočítám odmocninu:");
int a = int.Parse(Console.ReadLine());
if (a > 0)
{
    Console.WriteLine("Zadal jsi číslo větší než 0, to znamená, že ho mohu odmocnit!");
    double o = Math.Sqrt(a);
    Console.WriteLine("Odmocnina z čísla " + a + " je " + o);
}
if (a <= 0)
    Console.WriteLine("Odmocnina ze záporného čísla neexistuje!");
Console.WriteLine("Děkuji za zadání");
Console.ReadKey();

Všimněte si, že musíme pokrýt i případ, kdy se a == 0, nejen když je menší. Kód však můžeme výrazně zjednodušit pomocí klíčového slova else, které vykoná následující příkaz nebo blok příkazů v případě, že se podmínka neprovede:

Console.WriteLine("Zadej nějaké číslo, ze kterého spočítám odmocninu:");
int a = int.Parse(Console.ReadLine());
if (a > 0)
{
    Console.WriteLine("Zadal jsi číslo větší než 0, to znamená, že ho mohu odmocnit!");
    double o = Math.Sqrt(a);
    Console.WriteLine("Odmocnina z čísla " + a + " je " + o);
}
else
    Console.WriteLine("Odmocnina ze záporného čísla neexistuje!");
Console.WriteLine("Děkuji za zadání");
Console.ReadKey();

Kód je mnohem přehlednější a nemusíme vymýšlet opačnou podmínku, což by v případě složené podmínky mohlo být někdy i velmi obtížné. V případě více příkazů by byl za else opět blok { }.

Klíčové slovo else se také využívá v případě, kdy potřebujeme v příkazu manipulovat s proměnnou z podmínky a nemůžeme se na ni tedy ptát potom znovu. Program si sám pamatuje, že se podmínka nesplnila a přejde do větve else. Ukažme si to na příkladu: Mějme číslo a, kde bude hodnota 0 nebo 1 a po nás se bude chtít, abychom hodnotu prohodili (pokud tam je 0, dosadíme tam 1, pokud 1, dosadíme 0). Naivně bychom mohli kód napsat takto:

int a = 0; // do a si přiřadíme na začátku 0

if (a == 0) // pokud je a 0, dáme do něj jedničku
    a = 1;
if (a == 1) // pokud je a 1, dáme do něj nulu
    a = 0;

Console.WriteLine(a);
Console.ReadKey();

Nefunguje to, že? Pojďme si projet, co bude program dělat. Na začátku máme v a nulu, první podmínka se jistě splní a dosadí do a jedničku. No ale rázem se splní i ta druhá. Co s tím? Když podmínky otočíme, budeme mít ten samý problém s jedničkou. Jak z toho ven? Ano, použijeme else.

int a = 0; // do a si přiřadíme na začátku 0

if (a == 0) // pokud je a 0, dáme do něj jedničku
    a = 1;
else // pokud je a 1, dáme do něj nulu
    a = 0;

Console.WriteLine(a);
Console.ReadKey();

Podmínky je možné skládat a to pomocí dvou základních logických operátorů:

Operátor C-like Zápis
A zároveň &&
Nebo ||

Na české klávesnici je píšeme za pomoci Pravého Alt a kláves W a C, mnemotechnickou pomůcku si k tomu jistě domyslíte :) :

Operátory and a or

Uveďme si příklad:

Console.WriteLine("Zadejte číslo v rozmezí 10-20:");
int a = int.Parse(Console.ReadLine());
if ((a >= 10) && (a <= 20))
    Console.WriteLine("Zadal jsi správně");
else
    Console.WriteLine("Zadal jsi špatně");
Console.ReadKey();

S tím si zatím vystačíme, operátory se pomocí závorek samozřejmě dají kombinovat.

Console.WriteLine("Zadejte číslo v rozmezí 10-20 nebo 30-40:");
int a = int.Parse(Console.ReadLine());
if (((a >= 10) && (a <= 20)) || ((a >=30) && (a <= 40)))
    Console.WriteLine("Zadal jsi správně");
else
    Console.WriteLine("Zadal jsi špatně");
Console.ReadKey();

switch

Konstrukce switch je převzatá z jazyka C (jako většina gramatiky C#). Umožňuje nám zjednodušit (relativně) zápis více podmínek pod sebou. Vzpomeňme si na naši kalkulačku v prvních lekcích, která načetla 2 čísla a vypočítala všechny 4 operace. Nyní si ale budeme chtít zvolit, kterou operaci chceme. Bez switche bychom napsali kód podobný tomuto:

Console.WriteLine("Vítejte v kalkulačce");
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;
if (volba == 1)
    vysledek = a + b;
else
if (volba == 2)
    vysledek = a - b;
else
if (volba == 3)
    vysledek = a * b;
else
if (volba == 4)
    vysledek = a / b;
if ((volba > 0) && (volba < 5))
    Console.WriteLine("Výsledek: {0}", vysledek);
else
    Console.WriteLine("Neplatná volba");
Console.WriteLine("Děkuji za použití kalkulačky, aplikaci ukončíte libovolnou klávesou.");
Console.ReadKey();

Konzolová aplikace
Vítejte v kalkulačce
Zadejte první číslo:
3,14
Zadejte druhé číslo:
2,72
Zvolte si operaci:
1 - sčítání
2 - odčítání
3 - násobení
4 - dělení
2
Výsledek: 0,42
Děkuji za použití kalkulačky, aplikaci ukončíte libovolnou klávesou.

Všimněte si, že jsme proměnnou vysledek deklarovali na začátku, jen tak do ni můžeme potom přiřazovat. Kdybychom ji deklarovali u každého přiřazení, C# by kód nezkompiloval a vyhodil chybu redeklarace proměnné. Proměnná může být deklarována (založena v paměti) vždy jen jednou. Bohužel C# není schopen poznat, zda je do proměnné vysledek opravdu přiřazena nějaká hodnota. Ozve se při výpisu na konzoli, kde se mu nelíbí, že může vypisovat proměnnou, která nemá přiřazenu hodnotu. Z tohoto důvodu na začátku dosadíme do vysledek nulu.

Další vychytávka je kontrola správnosti volby. Program by v tomto případě fungoval stejně i bez těch else, ale nač se dále ptát, když již máme výsledek.

Nyní si zkusíme napsat ten samý kód pomocí switche:

Console.WriteLine("Vítejte v kalkulačce");
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("Děkuji za použití kalkulačky, aplikaci ukončíte libovolnou klávesou.");
Console.ReadKey();

Vidíme, že kód je trochu přehlednější. Pokud bychom potřebovali v nějaké větvi switche spustit více příkazů, překvapivě je nebudeme psát do {} bloku, ale rovnou pod sebe. Blok {} nám zde nahrazuje příkaz break, který způsobí vyskočení z celého switche. Konstrukce switch může místo case x: obsahovat ještě možnost default:, která se vykoná v případě, že nebude platit žádný case. Je jen na vás, jestli budete switch používat, obecně se vyplatí jen při větším množství příkazů a vždy jde nahradit sekvencí if a else. Nezapomínejte na breaky. Samozřejmě lze použít switch i pro hodnoty stringové proměnné.

Protože je poslední kód delší, je jej třeba zleva správně odsazovat tabulátory, aby byly snadno vidět jeho jednotlivé větve. Ze začátku pro vás může být udržování odsazení problém, proto pro vás máme vychytávku - autoformat. Klávesová zkratka Ctrl + ED zformátuje otevřený dokument ve Visual Studiu do dokonalé podoby. K této funkci se můžete dostat i přes menu Edit -> Advanced -> Format Document (funkce Format Selection potom zformátuje jen vybranou část kódu).

To bychom měli.

V následujícím cvičení, Řešené úlohy k 5. lekci C# .NET, si procvičíme nabyté zkušenosti z předchozích lekcí.


 

Stáhnout

Staženo 1038x (45.8 kB)
Aplikace je včetně zdrojových kódů v jazyce C#

 

Předchozí článek
Řešené úlohy k 4. lekci C# .NET
Všechny články v sekci
Základní konstrukce jazyka C# .NET
Článek pro vás napsal David Čápka
Avatar
Jak se ti líbí článek?
86 hlasů
Autor pracuje jako softwarový architekt a pedagog na projektu ITnetwork.cz (a jeho zahraničních verzích). Velmi si váží svobody podnikání v naší zemi a věří, že když se člověk neštítí práce, tak dokáže úplně cokoli.
Unicorn university Autor sítě se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.
Aktivity (23)

 

 

Komentáře
Zobrazit starší komentáře (122)

Avatar
David Holohlavský:4. března 0:24

Ahoj. Zjišťoval jsem rozdíl mezi relačními operátory a logickými operátory. Relační operátory slouží k porovnávání dvou hodnot – nejčastěji se jedná o číselné hodnoty. Logické operátory pracují s operandy jako s logickými, tedy pravdivostními hodnotami true (pravda) a false (nepravda). Podle těchto definic by obecná negace patřila do logických operátorů, protože pracuje s pravdivostními hodnotami. Např: !(false). Děkuji.

 
Odpovědět
4. března 0:24
Avatar
Robin Blažek:22. března 10:06

Ahoj, díky moc za další parádní článek. S takovými podklady je doslova radost se C# učit.

 
Odpovědět
22. března 10:06
Avatar
Martin Košař:13. června 9:25

díky moc za lekce! Učím se doma, od nuly a tohle mi moc pomáhá.

 
Odpovědět
13. června 9:25
Avatar
Savi
Člen
Avatar
Savi:17. června 7:47

Ahoj,

při opakování lekce jsem měl v kódu toto:

while (odpoved != "ano" || odpoved != "ne")
                {
                    Console.WriteLine("zadej odpoved jeste jednou: ");
                    odpoved = Console.ReadLine();
                }

ale to nefungovalo.

Fungovalo to až jako:

while (odpoved != "ano" && odpoved != "ne")
                {
                    Console.WriteLine("zadej odpoved jeste jednou: ");
                    odpoved = Console.ReadLine();
                }

Proč nefunguje ta první možnost ? Jde to nějak slovně popsat? Děkuji

 
Odpovědět
17. června 7:47
Avatar
Alesh
Překladatel
Avatar
Odpovídá na Savi
Alesh:17. června 9:26

Tak jde vlastně o negaci složených výroků, viz např. http://www.mocz.pecos.cz/…-vyroku.html
Začněme od situace, kdybys chtěl opak, tj. podmínku, že odpověď je "ano" nebo je "ne":

while (odpoved == "ano" || odpoved == "ne")

Jasné, že? Ty ji potřebuješ ale celou znegovat:

while (!(odpoved == "ano" || odpoved == "ne"))

Furt jasné, viď? Dokud odpověď není ("ano" nebo "ne").
A teď se mrkni do toho odkazu:
A∨B negujeme: ¬(A ∨ B), což je ekvivalentní ¬A ∧ ¬B, čili předešlý kód lze zapsat i tak, jak jsi to nakonec vyzkoumal ty sám :-):

while (odpoved != "ano" && odpoved != "ne")

Dokud odpověď není "ano" a není ani "ne".
Čeština je v tomto poněkud matoucí, však si všimni jak oproti angličtině nelogicky tvoříme zápory.

Editováno 17. června 9:27
 
Odpovědět
17. června 9:26
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Savi
Člen
Avatar
Odpovídá na Alesh
Savi:17. června 13:48

Děkuji za super vysvětlení ! :-)

 
Odpovědět
17. června 13:48
Avatar
Bohumír Bednařík:30. června 19:25

V článku mi chybí uvedení konstrukce switch/case takové, ve které by bylo možné otestovat více hodnot najednou. Uvedu příklad: Budu mít cyklus o 100 průchodech a chci řešit různé výstupy pro intervaly od 0 do 10, od 11 do 20, atd. Přece nebudu vypisovat všechny hodnoty stylem:

case 0:
case 1:
case 2:
atd.

Jsem úplný začátečník v C#. Ve VB bych to napsal zhruba jako:

case 0 to 10:
case 11 to 20:
atd.

Jak na to? Našel jsem si řešení následujícího typu, ale nevím, jestli je to tak správně:

case int j when ((j>0) && (j<11)):
 
Odpovědět
30. června 19:25
Avatar
Odpovídá na Alesh
Bohumír Bednařík:30. června 20:26

Takže jsem si to našel vlastně správně. Oproti VB je to ale dost "opruz".

 
Odpovědět
30. června 20:26
Avatar
Andrea K.
Člen
Avatar
Andrea K.:26. srpna 18:04

jenom technicka - formatovani mi bere Ctrl + KD :)

 
Odpovědět
26. srpna 18:04
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 10 zpráv z 132. Zobrazit vše