5. díl - Podmínky (větvení)

C# .NET Základní konstrukce Podmínky (větvení) American English version English version

V minulém dílu jsme si podrobně probrali datové typy. 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í dí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. Vyzkoušejme si to:

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

Výstup programu:

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 !

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();
Program pro výpočet druhé odmocniny v C#.NET

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í hodnotu 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 { }.

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 sekce 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, dáme tam 1, pokud 1, dáme tam 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 ||

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

Switch je konstrukce, 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();
jednoduchá konzolová kalkulačka v C#.NET

Všimněte si, že jsme proměnnou výsledek 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. 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. Switch jde samozřejmě udělat i pro hodnoty stringové proměnné.

To bychom měli, příště nás čekají pole a cykly, tím dovršíme základní znalosti, máte se na co těšit :)


 

Stáhnout

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

 

  Aktivity (4)

Článek pro vás napsal David Čápka
Avatar
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 College Autor se informační technologie naučil na Unicorn College - prestižní soukromé vysoké škole IT a ekonomie.

Jak se ti líbí článek?
Celkem (42 hlasů) :
4.833344.833344.833344.833344.83334


 


Miniatura
Předchozí článek
Cvičení k 4. lekci C# .NET
Miniatura
Všechny články v sekci
Základní konstrukce jazyka C#
Miniatura
Následující článek
Cvičení k 5. lekci C# .NET

 

 

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

Avatar
krepsy3
Redaktor
Avatar
krepsy3:

Ještě bych doplnil, že samotný příkaz

double o = Math.Sqrt(a);

Ti nadeklaruje proměnnou o typu double, do které uloží druhou odmocninu z proměnné a.

Odpovědět  +1 5. června 9:10
Programátor je stroj k převodu kávy na kód.
Avatar
krepsy3
Redaktor
Avatar
krepsy3:

No ty kráso, s tím bych se prdět nectěl. Mám pocit, že do něčeho takového ses měl pustit, až když budeš vědět něco více, jelikož tento kód samozřejmě bude fungovat, ale je to s odpuštěním prasárna. Totiž: jakmile chceš cokoli upravit, musíš to v tomto kódu hledat, a upravit to pro každou otázku - u deseti se to sice jakž takž dá, ale třeba u sta? Jinak tam máš i nějaké gramatické chyby a překlepy - a zase, bude se ti to špatně opravovat. Někdo tu psal, že mu to u šesté otázky spadne - nedělo by se to, pokud by hra měla správný objektový návrh. Já plně chápu, že to zatím neumíš, a vlastně oceňuji snahu i odvahu se do něčeho takového pouštět. Nedávno jsem si například sám procházel moje staré prográmky z doby, kdy jsem byl u těchto tutoriálů, a zjistil jsem, jak je o strašný (goto, statický návrh...). Takže až budeš kousek dál (což bude dost brzo, pokud nepolevíš ;)), jistě mě pochopíš a také se ti podaří přepsat tento prográmek o něco lépe.

Odpovědět  +1 5. června 9:25
Programátor je stroj k převodu kávy na kód.
Avatar
cisco
Člen
Avatar
Odpovídá na krepsy3
cisco:

Zdravím děkuji za upřímnou odpověď už jsem postoupil a něco dál a tak už vím jak ten kód vylepšit. Jinak z mé strany si myslim že každá negativní odpověď mi něco přidává, pokud to tedy není nějaké urážlivé :-)

 
Odpovědět 10. června 14:17
Avatar
Milan Šmídl:

Ahoj,

if (((ycoordinate * ycoordinate) + (xcoordinate * xcoordinate) <= 25) && !((5 >= xcoordinate >= -1) && (5 >= ycoordinate >= 1)))
Console.Write­Line("zadaný bod lezi v kruhu a zaroven mimo ctverec");

poraďte prosím, chci napsat... pokud soucet mocnin souradnic je menší anebo roven 25 a zároveň NEJSOU hodnoty souradnic z daného Intervalu (-1;5) a (1;5) - nesmí býr ani v jednom případě!!! napiš "zadaný bod lezi v kruhu a zaroven mimo ctverec"

Děkuji..

 
Odpovědět 11. srpna 11:25
Avatar
gcx11
Redaktor
Avatar
Odpovídá na Milan Šmídl
gcx11:

Ahoj, C# neumí skládat podmínky k sobě jako třeba Python, takže správně bys to měl mít takto:

if ((x*x+y*y <= 25) && ((x <= -1) || (x >= 5)) && ((y <= 1) || (y >= 5)))
Editováno 11. srpna 13:54
 
Odpovědět 11. srpna 13:54
Avatar
Odpovídá na gcx11
Milan Šmídl:

Dekuji moc, uz jsem na to prisel sam, kod mi uz bezi, ale kazdopadne dekuji

 
Odpovědět 12. srpna 7:40
Avatar
matyas.janos
Člen
Avatar
matyas.janos:

Dobrý den můžu se zeptat co dělám blbě? Vymyslel jsem si jednoudůchý program na vyzkoušení podmínek, který se zkládá ze dvou podmínek IF a jedné else. V první podmínce musím napsat ANO aby se splnila a u druhé NE a potom je tam else když se nesplní ani jedna. Program funguje v celku v pohodě až na to že když zadám ano což je první podmínka splní se mi také podmínka ELSE takže mi vyjede že jsem napsal Ano a zároven že jsem navybral ani jednu možnost. U podmínky ne to funguje v pohodě. Poradtě prosím co dělám blbě za jakoukoliv poradu budu vděčnej. Také přikládám kód:

Console.WriteLine("napište ano nebo ne!");
string volba = Console.ReadLine();
if (volba == "ano")
    Console.WriteLine("Zadal jsi ano!");
if (volba == "ne")
    Console.WriteLine("Zadal jsi ne!");
else
    Console.WriteLine("nezadal jsi ani jedno!!!");
Console.WriteLine("Děkuji za zadání");
Console.ReadKey();
 
Odpovědět 22. září 22:49
Avatar
Lukas C#
Redaktor
Avatar
Odpovídá na matyas.janos
Lukas C#:

To druhé "if" přepiš na "else if", aby se ten rozhodovací blok bral jako tři podmínky, z nichž se jedna splní a ostatní se přeskočí.

 
Odpovědět  +1 22. září 22:58
Avatar
jakoubek.stanislav:

Jen malá drobnůstka, pro šťouraly ;-) , ale proč by nešla odmocnit nula? %P . Ale jinak výborná učebnice na příkladech, jsem nadšenej

 
Odpovědět 10. listopadu 7:24
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 71. Zobrazit vše