Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
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:

if (15 > 5)
    cout << "Pravda" << endl;
cout << "Program zde pokracuje dal" << endl;
cin.get();

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

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

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:

#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;
}

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:

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

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:

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

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:

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

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;

cout << a << endl;
cin.get();

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:

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

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

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

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:

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

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.

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

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 323x (8.14 kB)
Aplikace je včetně zdrojových kódů v jazyce C++

 

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í:
164 hlasů
Autor se věnuje spoustě zajímavých věcí ze světa informatiky a grafiky
Aktivity