Válí se ti projekty v šuplíku? Dostaň je mezi lidi a získej cool tričko a body na profi IT kurzy v soutěži ITnetwork summer 2017!
Přidej si svou IT školu do profilu a najdi spolužáky zde na síti :)

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

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

ONEbit hosting Unicorn College Tento obsah je dostupný zdarma v rámci projektu IT lidem. Vydávání, hosting a aktualizace umožňují jeho sponzoři.

V minulé lekci C#.NET kurzu, Typový systém podruhé: Datové typy, 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í 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. 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 !

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í 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();

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 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. V příští lekci, Cykly v C#, nás čekají pole a cykly, tím dovršíme základní znalosti, máte se na co těšit :)


 

Stáhnout

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

 

 

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

 

 

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

Avatar
pocitac770
Redaktor
Avatar
pocitac770:7. března 13:29

V tom případě se omlouvám za nedorozumění, již chápu, čím to bylo, celou dobu jsem se při hledání zaměřoval na ReadKey() a nevšiml si toho Read(). Read() přečte jeden znak z bufferu konzole, ale pro načtení toho znaku je ho potřeba odentrovat, čímž se přidají dva (číslo a enter), ale ten enter tam zůstává, tudíž to je to, co způsobí "vyprázdnění" dalšího inputu, čtení proběhne standartně, ale nikoliv tak, jak bys to očekával. Zde byl zakopaný pes...

Editováno 7. března 13:30
 
Odpovědět 7. března 13:29
Avatar
Odpovídá na pocitac770
Bruno Schwarzbach:7. března 15:51

Děkuji za vysvětlení funkce Read(), to se mi na programován ílíbí, vše má nějaké logické vysvětlení... včera mi to tak nepřišlo, jsem v zoufalství zkoušel i měnit klávesnici :-)

 
Odpovědět 7. března 15:51
Avatar
Martin
Člen
Avatar
Martin:3. dubna 16:49

Ahoj. A co teda goto?
nepouzivat? neni to vhode?
jaka je vhodna nahrada za goto?
Dekuji

 
Odpovědět 3. dubna 16:49
Avatar
pocitac770
Redaktor
Avatar
Odpovídá na Martin
pocitac770:3. dubna 17:32

Takhle, úplně do hloubky nejsem zrovna vhodný člověk na objasňování tohoto "jevu", nikdy jsem v Céčku pořádně nedělal, to yb musel odpovědět někdo v této oblasti zkušenější.
Každopádně z doslechu to mám "naposloucháno" tak, že nás vyšší jazyky odstiňují od těchto nízkoúrovňových příkazů, protože v nich vznikaly dosti chyby, a samy nastiňují mnohem jednodušší cesty. Například já, který jsem tento příkaz nikdy nepoužíval si ani jeho použití představit nedokážu. Jsem již naučen na psychologii Objektově orientavaného programování, ti, co programovali strukturovaně (Nebo ještě níže? Goto je zrovna věc, která myslím sahá až do dob Assembleru, co si teď vzpomínám) zase vidí celý kód z poněkud jiného úhlu pohledu.
Například co já bych viděl, takové to "vracení se na určitou část kódu" jde docílit while cykly "místo" ifů, pokud jde o spouštění určitých samostatných kusů kódů, tak se jedná o metody.... Jak říkám, já konkrétní příklady popsat neumím :D

 
Odpovědět  +1 3. dubna 17:32
Avatar
Martin
Člen
Avatar
Martin:3. dubna 19:13

;-)
dekuji

 
Odpovědět 3. dubna 19:13
Avatar
Odpovídá na Martin
Michal Štěpánek:4. dubna 10:47

Příkaz "goto" jsem naposledy použil někdy v roce 1988, když jsme na střední škole "programovali" v BASICu na počítačích "IQ151". Abych pravdu řekl ani nevím, že (jestli) se při současném OOP dá použít a nenapadá mě (při mém "pseudoprogra­mování") k čemu by se mi takový příkaz hodil, když, jak psal pocitac770 se dá nahradit různými jinými způsoby...

Odpovědět 4. dubna 10:47
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Jan Mareš
Člen
Avatar
Jan Mareš:3. května 22:39

Ahoj prosím o radu při psaní aplikace jsem narazil na pár chyb a nevím si rady s napsáním aplikace za pomocí if a else:

zkoušel jsem psát tuto aplikaci s uživatelským vstupem za pomocí podmínek:

Console.Title = "náhrada řetězce";
           string text = "Jsem skvělý programátor";
           text = text.Replace("skvělý", "špatný");
           Console.WriteLine(text);
           Console.ReadKey();

Pokud to napíši takto vše funguje:

Console.Title = "Záměna";
           Console.WriteLine("Napiš kde jsi.");
           string text = Console.ReadLine();
           switch (text)
           {
               case "jsem doma":
                   Console.WriteLine("Jsem venku");

                   break;
               case "jsem venku":
                   Console.WriteLine("Jsem doma");

                   break;

               default:
                   Console.WriteLine(text);

                   break;
           }

           Console.ReadKey();

Když jsem se to snažil napsat takto ukazuje mi to chybu u poslední složené závorky před else,zajímá mne co píši špatně:

Console.Title = "Záměna";
           Console.WriteLine("Napiš kde jsi.");
           string text = Console.ReadLine();
           switch (text)
           {
               case "jsem doma":
                   Console.WriteLine("Jsem venku");

                   break;
               case "jsem venku":
                   Console.WriteLine("Jsem doma");

                   break;
           }

           else
           Console.WriteLine(text);
           Console.ReadKey();

a za pomocí podmínek if a else se mi to nedaří napsat,zkoušel jsem různé varianty a úpravy ale stále mi to ukazuje tutéž chybu,Zajímalo by mne jak to napsat a co dělám špatně děkuji za rady.

Console.Title = "Záměna";
Console.WriteLine("Napiš kde jsi.");
string text = Console.ReadLine();
    if "jsem doma":
    {
    Console.WriteLine("Jsem venku");
}

    if "jsem venku":

        {
        Console.WriteLine("Jsem doma");
}

else
Console.WriteLine(text);
Console.ReadKey();
 
Odpovědět 3. května 22:39
Avatar
pocitac770
Redaktor
Avatar
Odpovídá na Jan Mareš
pocitac770:3. května 23:22

To proto že else patří k if, nikoliv ke switch, u něj se jako nenalezení vhodné možnosti používá možnost default (viz poslední normální odstavec lekce)

Editováno 3. května 23:22
 
Odpovědět  +1 3. května 23:22
Avatar
pocitac770
Redaktor
Avatar
Odpovídá na Jan Mareš
pocitac770:3. května 23:26

K poslednímu kódu, je to absolutní patlanina, jako by jsi nikdy nečetl seriál, if se používá spolu s boolean podmínkou v závorce, nikoliv s nějakým textem odnikud, taktéž se tam nepíše dvojtečka, a pokud by jsi přesto ten kód napsal správně, tak by ti nefungoval, protože při splnění první podmínky by se následně splnila i druhá, používej if - if else - else. Radši si přečti tuto lekci celou ještě jednou nebo radši dvakrát...

 
Odpovědět  +1 3. května 23:26
Avatar
Jan Mareš
Člen
Avatar
Odpovídá na pocitac770
Jan Mareš:4. května 9:20

Toto mi zatím dělá problém,vím že ke switch patří default ale když se podívám na tu kalkulačku za pomocí switche tak tam má také else,ale když na to zpětně koukám tak už to vidím,to else tam nepatří ke switch ale k tomu if,nevšiml jsem si. A k tomu poslednímu kodu,když jsem ho psal tak jsem k přehledu používal tu kalkulačku a tam má také psané if-else if,zatím to použít neumím.To že se to používá společně s booleanem,mi nějak uniklo,moc děkuji,možná už vím jak to napsat,snad to půjde.

 
Odpovědět 4. května 9:20
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 88. Zobrazit vše