Lekce 5 - Podmínky (větvení) v C# .NET
V předešlém cvičení, Řešené úlohy ke 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íšou úplně stejně jako ve všech C-like jazycích, což začátečníkům samozřejmě vysvětlíme. 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:
Vyzkoušejme si to:
{CSHARP_CONSOLE}
if (15 > 5)
Console.WriteLine("Pravda");
Console.WriteLine("Program zde pokračuje dál");
Console.ReadKey();
{/CSHARP_CONSOLE}
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á:
{CSHARP_CONSOLE}
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();
{/CSHARP_CONSOLE}
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 | ! |
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:
{CSHARP_CONSOLE}
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();
{/CSHARP_CONSOLE}
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:
{CSHARP_CONSOLE}
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();
{/CSHARP_CONSOLE}
Všimněme 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:
{CSHARP_CONSOLE}
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();
{/CSHARP_CONSOLE}
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
tedy na ni 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:
{CSHARP_CONSOLE}
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();
{/CSHARP_CONSOLE}
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 tentýž problém s jedničkou. Jak z toho ven?
Ano, použijeme else
.
{CSHARP_CONSOLE}
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();
{/CSHARP_CONSOLE}
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 pomocí Pravého Alt a kláves W a C:
Uveďme si příklad:
{CSHARP_CONSOLE}
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();
{/CSHARP_CONSOLE}
S tím si zatím vystačíme, operátory lze samozřejmě pomocí závorek kombinovat.
{CSHARP_CONSOLE}
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();
{/CSHARP_CONSOLE}
switch
Konstrukce switch
je převzatá z jazyka C (jako většina gramatiky C#). Umožňuje
nám (relativně) zjednodušit 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 konstrukce switch
bychom napsali kód podobný
tomuto:
{CSHARP_CONSOLE}
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();
{/CSHARP_CONSOLE}
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ěme si, že jsme proměnnou vysledek
deklarovali na
začátku, protože jen tak do ní potom můžeme přiřazovat. Kdybychom ji
deklarovali u každého přiřazení, C# by kód nezkompiloval a vyhodil by
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 else
, ale nač se dále ptát,
když již máme výsledek.
Nyní si zkusíme napsat tentýž kód pomocí konstrukce
switch
:
{CSHARP_CONSOLE}
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();
{/CSHARP_CONSOLE}
Vidíme, že kód je trochu přehlednější. Pokud bychom potřebovali v
nějaké větvi konstrukce switch
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é konstrukce switch
.
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 nás, jestli budeme
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ínejme na příkaz break
. 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 jednotlivé větve kódu. 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).
Switch na řádku
Autoři C# za poslední roky vychrlili spoustu nové syntaxe. Určitě se jí
teď nenechme zmást, ale pro úplnost si ukažme, jak se dá zápis konstrukce
switch
ještě zjednodušit.
Osobně bych doporučoval tuto syntaxi spíše nepoužívat, protože je poměrně nestandardní, ale můžete na ni narazit v cizích zdrojových kódech.
Představme si, že máme program na vyjádření teploty slovy a máme
různé hodnoty a rozsahy, podle kterých chceme říci, jak venku je. Od C# 9
můžeme takový switch
napsat mnohem úsporněji:
int teplota = 12; string teplotaSlovy = teplota switch { < -5 => "Mrzne", 0 or 100 => "Mrzne nebo vře", >= -5 and <= 5 => "Zima", > 5 and < 15 => "Chladno", >= 15 and <= 25 => "Teplo", > 25 => "Horko" };
Do nové proměnné teplotaSlovy
ukládáme a z
teplota
čteme. Můžeme využít porovnávací znaménka
(>
, <
, <=
, >=
) a
také slova and
(a zároveň) a or
(nebo). Default
bychom nahradili následovně pomocí podtržítka _
:
_ => Console.WriteLine("Nevalidní hodnota");
(U tohoto ukázkového příkladu konstrukce switch by se
default
samozřejmě nikdy nespustil.)
Na české klávesnici píšeme podtržítko _
pomocí Shift a následující klávesy:
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í.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 1363x (45.8 kB)
Aplikace je včetně zdrojových kódů v jazyce C#