NOVINKA - Online rekvalifikační kurz Python programátor. Oblíbená a studenty ověřená rekvalifikace - nyní i online.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 5 - Podmínky (větvení) v C++

V minulé lekci, Typový systém podruhé - Datové typy v C++, jsme si podrobně probrali datové typy v C++.

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

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:

Klikni pro editaci
  • if (15 > 5)
        cout << "Pravda" << endl;
    cout << "Program zde pokracuje dal" << endl;
    cin.get();
    
    • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

    Výstup programu:

    Konzolová aplikace
    Pravda
    Program zde pokracuje dal

    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á:

    Klikni pro editaci
    • cout << "Zadej nejake cislo" << endl;
      int a;
      cin >> a;
      if (a > 5)
          cout << "Zadal jsi cislo vetsi nez 5!" << endl;
      cout << "Dekuji za zadani" << endl;
      cin.get(); cin.get();
      
      • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

      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 (z true udělat false a naopak), napíšeme ho do závorky a před něj vykřičník.

      Když budeme chtít při splnění podmínky vykonat více než jen jeden příkaz, musíme příkazy vložit do bloku ze složených závorek:

      Klikni pro editaci
      • #include <iostream>
        #include <cmath>
        using namespace std;
        
        int main()
        {
            cout << "Zadej nejake cislo, ze ktereho spocitam odmocninu:" << endl;
            int a;
            cin >> a;
            if (a >= 0)
            {
                cout << "Zadal jsi nezaporne cislo, to znamena, ze ho mohu odmocnit!" << endl;
                double o = sqrt(double(a));
                cout << "Odmocnina z cisla " << a << " je " << o << endl;
            }
            cout << "Dekuji za zadani" << endl;
            cin.get(); cin.get();
            return 0;
        }
        
        • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

        Výsledek:

        Konzolová aplikace
        Zadej nejake cislo, ze ktereho spocitam odmocninu:
        150
        Zadal jsi nezaporne cislo, to znamena, ze ho mohu odmocnit!
        Odmocnina z cisla 150 je 12.2474
        Dekuji za zadani

        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 funkci sqrt(), která je spolu s řadou dalších užitečných matematických funkcí definována v souboru cmath (Nezapomeňte ji includovat, pokud chcete funkci používat). sqrt() vrací hodnotu jako double. Protože ale dokáže pracovat s několika datovými typy, musíme jí říct, kterou verzi chceme použít. Proměnnou a tedy přetypujeme na double. To se dá provést několika způsoby:

        1. typ(hodnota)
        2. (typ)hodnota
        3. (typ)(hodnota)

        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:

        Klikni pro editaci
        • cout << "Zadej nejake cislo, ze ktereho spocitam odmocninu:" << endl;
          int a;
          cin >> a;
          if (a >= 0)
          {
              cout << "Zadal jsi nezaporne cislo, to znamena, ze ho mohu odmocnit!" << endl;
              double o = sqrt(double(a));
              cout << "Odmocnina z cisla " << a << " je " << o << endl;
          }
          if (a < 0)
              cout << "Odmocnina ze zaporneho cisla neexistuje!" << endl;
          cout << "Dekuji za zadani" << endl;
          cin.get(); cin.get();
          
          • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

          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:

          Klikni pro editaci
          • cout << "Zadej nejake cislo, ze ktereho spocitam odmocninu:" << endl;
            int a;
            cin >> a;
            if (a >= 0)
            {
                cout << "Zadal jsi nezaporne cislo, to znamena, ze ho mohu odmocnit!" << endl;
                double o = sqrt(double(a));
                cout << "Odmocnina z cisla " << a << " je " << o << endl;
            }
            else
                cout << "Odmocnina ze zaporneho cisla neexistuje!" << endl;
            cout << "Dekuji za zadani" << endl;
            cin.get(); cin.get();
            
            • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

            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 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:

            Klikni pro editaci
            • 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;
              
              cout << a << endl;
              cin.get();
              
              • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

              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.

              Klikni pro editaci
              • 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;
                
                cout << a << endl;
                cin.get();
                
                • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

                V C++ můžeme celou podmínku nahradit i tímto: a = !a;, což nám prohodí nulu a jedničku.

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

                Operátor C-like zápis Význam
                A zároveň && platí obojí
                Nebo || platí alespoň jedno

                Uveďme si příklad:

                Klikni pro editaci
                • cout << "Zadejte cislo v rozmezi 10-20:" << endl;
                  int a;
                  cin >> a;
                  if ((a >= 10) && (a <= 20))
                      cout << "Zadal jsi spravne" << endl;
                  else
                      cout << "Zadal jsi spatne" << endl;
                  cin.get(); cin.get();
                  
                  • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

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

                  Klikni pro editaci
                  • cout << "Zadejte cislo v rozmezi 10-20 nebo 30-40:" << endl;
                    int a;
                    cin >> a;
                    if (((a >= 10) && (a <= 20)) || ((a >=30) && (a <= 40)))
                        cout << "Zadal jsi spravne" << endl;
                    else
                        cout << "Zadal jsi spatne" << endl;
                    cin.get(); cin.get();
                    
                    • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

                    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 switch bychom napsali kód podobný tomuto:

                    Klikni pro editaci
                    • cout << "Vitejte v kalkulacce" << endl;
                      cout << "Zadejte prvni cislo:" << endl;
                      float a;
                      cin >> a;
                      cout << "Zadejte druhe cislo:" << endl;
                      float b;
                      cin >> b;
                      cout << "Zvolte si operaci:" << endl;
                      cout << "1 - scitani" << endl;
                      cout << "2 - odcitani" << endl;
                      cout << "3 - nasobeni" << endl;
                      cout << "4 - deleni" << endl;
                      int volba;
                      cin >> volba;
                      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))
                          cout << "Vysledek: " << vysledek << endl;
                      else
                          cout << "Neplatna volba" << endl;
                      cout << "Dekuji za pouziti kalkulacky, aplikaci ukoncite libovolnou klavesou." << endl;
                      cin.get(); cin.get();
                      
                      • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

                      Výsledek:

                      Konzolová aplikace
                      Vitejte v kalkulacce
                      Zadejte prvni cislo:
                      18
                      Zadejte druhe cislo:
                      9
                      Zvolte si operaci:
                      1 - scitani
                      2 - odcitani
                      3 - nasobeni
                      4 - deleni
                      4
                      Vysledek:2
                      Dekuji za pouziti kalkulacky, aplikaci ukoncite libovolnou klavesou.

                      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í, na konci podmínek by už neexistovala (existovala by jen do skončení bloku příkazů za if, my máme místo bloku příkazů jen 1 příkaz, takže by zanikla ihned po jeho provedení). Bohužel C++ není schopen poznat, zda je do proměnné vysledek opravdu přiřazena nějaká hodnota. 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í switch. Navíc k němu ale přidáme užitečný řádek kódu. Není zrovna hezké vypisovat jen znaky bez diakritiky. Proto zapneme podporu českých znaků. To dělá funkce setlocale() ze knihovny clocale.

                      Klikni pro editaci
                      • cout << "Vitejte v kalkulacce" << endl;
                        cout << "Zadejte prvni cislo:" << endl;
                        float a;
                        cin >> a;
                        cout << "Zadejte druhe cislo:" << endl;
                        float b;
                        cin >> b;
                        cout << "Zvolte si operaci:" << endl;
                        cout << "1 - scitani" << endl;
                        cout << "2 - odcitani" << endl;
                        cout << "3 - nasobeni" << endl;
                        cout << "4 - deleni" << endl;
                        int volba;
                        cin >> volba;
                        float vysledek = 0.0f;
                        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))
                            cout << "Vysledek:" << vysledek << endl;
                        else
                            cout << "Neplatna volba" << endl;
                        cout << "Dekuji za pouziti kalkulacky, aplikaci ukoncite libovolnou klavesou." << endl;
                        cin.get();cin.get();
                        
                        • Zkontroluj, zda výstupy programu odpovídají předloze. S jinými texty testy neprojdou.

                        Vidíme, že kód je trochu přehlednější. Pokud bychom potřebovali v nějaké větvi 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ého switch. Blok 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 příkazy break, pokud jej neuvedete, program propadne do další větve a to i když by nebyla splněná podmínka! V minulosti se takovéto propadávání využívalo schválně, dnešní IDE před tímto použitím ale spíše již varují.

                        To bychom měli.

                        V následujícím cvičení, Řešené úlohy ke 4.-5. lekci C++, 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 333x (8.14 kB)
                        Aplikace je včetně zdrojových kódů v jazyce C++

                         

                        Jak se ti líbí článek?
                        Před uložením hodnocení, popiš prosím autorovi, co je špatněZnaků 0 z 50-500
                        Předchozí článek
                        Typový systém podruhé - Datové typy v C++
                        Všechny články v sekci
                        Základní konstrukce jazyka C++
                        Přeskočit článek
                        (nedoporučujeme)
                        Řešené úlohy ke 4.-5. lekci C++
                        Článek pro vás napsal Zdeněk Pavlátka
                        Avatar
                        Uživatelské hodnocení:
                        208 hlasů
                        Autor se věnuje spoustě zajímavých věcí ze světa informatiky a grafiky
                        Aktivity