4. Operátory
  1. V našich programech jsme již použili několik operátorů. Nyní se s operátory seznámíme podrobněji. Operátory provádějí různé funkce na jednom, dvou nebo třech operandech. Operátory, které vyžadují jeden operand se nazývají unární. Např. ++ je unární operátor, který inkrementuje hodnotu svého operandu o 1 (zvětšuje o 1). Operátory, které vyžadují dva operandy jsou binární operátory. Např. = je binární operátor, který přiřazuje hodnotu svého pravého operandu do levého operandu. Máme také jeden operátor, který vyžaduje tři operandy. Jedná se o ternární operátor ? :, který je zkráceným tvarem příkazu if-else.

  2. Unární operátory mohou být prefixové nebo postfixové. Prefixový zápis znamená, že operátor je zapsán před svým operandem:
    operátor operand
    Postfixový zápis znamená, že operátor je za svým operandem.
    operand operátor
    Všechny binární operátory používají infixový zápis, ve kterém operátor je mezi svými operandy.
    operand1 operátor operand2
    Ternární operátor je také infixový, každá část operátoru je zobrazena mezi operandy:
    výraz ? operand1 : operand2
    Mimo provedení operace, operátor také vrací hodnotu. Hodnota a její typ závisí na operátoru a typu jeho parametrů. Např. aritmetické operátory, které provádějí základní aritmetické operace jako je sčítání, odečítání, vracejí výsledek prováděné operace. Datový typ výsledku aritmetické operace závisí na datových typech svých operandů. Jestliže sčítáme dvě celá čísla, získáme celé číslo. Operace je určena k výpočtu svého výsledku. Operátory můžeme rozdělit do několika skupin: aritmetické, relační, porovnávací, bitové, logické a přiřazovací. Dále se budeme podrobněji zabývat jednotlivými skupinami operátorů.
  3. Aritmetické operátory. C a C++ podporuje různé aritmetické operátory pro všechny číselné hodnoty (celočíselné i reálné). Tyto operátory zahrnují + (sčítání), - (odečítání), * (násobení), / (dělení) a % (zbytek po dělení). Např. následující kód můžeme použít pro sečtení dvou čísel:

  4. operand1 + operand2
    Nebo následující kód můžeme použít k výpočtu zbytku dělení operandu1 operandem2:
    operand1 % operand2
    Binární aritmetické operátory jsou popsány v následující tabulce:
    Operátor
    Použití
    Popis
    +
    operand1 + operand2
    Sečte operand1 a operand2
    -
    operand1 - operand2
    Odečte operand2 od operandu1
    *
    operand1 * operand2
    Násobí operand1 operandem2
    /
    operand1 / operand2
    Dělí operand1 operandem2
    %
    operand1 % operand2
    Vypočítává zbytek po dělení operandu1 operandem2
    Jazyk C++ rozšiřuje definici operátoru + i na spojování řetězců. Např. v jednom z následujících programů uvidíme
    "Výsledek: " + AnsiString(Edit1->Text.ToInt() / 60) + ":" + AnsiString(Edit1->Text.ToInt() % 60)
    Jsou zde spojeny čtyři řetězce.
    Operátory + a - mají i unární verzi, která provádí následující operace:
    Operátor
    Použití
    Popis
    +
     + operand
    Rozšiřuje na int (pro short a char)
    -
     - operand
    Změna znaménka
    Jsou další dva operátory: ++ (inkrementuje svůj operand o 1) a -- (dekrementuje svůj operand o 1). Např. pocet++;. Povšimněte si, že operátor ++ je zobrazen za svým operandem. Je to postfixová verze operátoru. ++ má také prefixovou verzi, kde ++ je před svým operandem. Obě verze tohoto operátoru inkrementují operand o 1. Můžeme si položit otázku, jaký je rozdíl mezi oběma verzemi tohoto operátoru. Každá z těchto verzí vypočítává jinou hodnotu: operand++ vypočítává hodnotu operandu před operací inkrementace a ++operand vypočítává hodnotu operandu po operaci inkrementace. Předpokládejme, že hodnota proměnné pocet je 5. Po provedení příkazu  pocet++; je hodnota proměnné pocet rovna 6, ale příkaz pocet++; má hodnotu 5. Při použití prefixové verze je po provedení příkazu hodnota proměnné pocet také 6, ale hodnota příkazu ++pocet; je  6. Tento rozdíl je podstatný, když hodnota příkazu je použita ve složitějších výpočtech, v příkazech řídících běh programu nebo i někdy jindy. Např. následující cyklus bude proveden o jedenkrát méně, jestliže pocet++ nahradíme ++pocet:
    do {
       ...
    } while (pocet++ < 6);
    Podobně, -- má také prefixovou a postfixovou verzi, které pracují stejným způsobem jako ++. Operátor -- dekrementuje hodnotu svého operandu (zmenšuje ji o 1).
  5. Uvažujme následující program:

  6. int x = 10;
    cout << "x = " << x++ << endl;
    cout << "x = " << x << endl;
    cout << "x = " << ++x << endl;
    cout << "x = " << x << endl;
    Pokuste se odhadnout, jaké hodnoty tato část programu vypíše. Svůj odhad si ověřte (vytvořte z těchto příkazů konzolovou aplikaci).
  7. Relační a logické operátory. Relační operátor porovnává dvě hodnoty a určuje jejich vzájemný vztah. Např. != zjišťuje nerovnost svých dvou operandů. Jestliže výsledek je pravdivý, pak je vrácena nenula (true) a není-li pravdivý je vrácena nula (false). V následující tabulce je uveden přehled relačních operátorů:
  8. Operátor
    Použití
    Je pravdivé, když
    <
    operand1 < operand2
    operand1 je menší než operand2
    <=
    operand1 <= operand2
    operand1 je menší nebo roven než operand2
    >
    operand1 > operand2
    operand1 je větší než operand2
    >=
    operand1 >= operand2
    operand1 je větší nebo roven než operand2
    ==
    operand1 == operand2
    operandy se rovnají
    !=
    operand1 != operand2
    operandy se nerovnají
    Relační operátory se často používají s logickými operátory k vytvoření složitější podmínky. Jedním z těchto operátorů je &&, který provádí operaci logického součinu. Např. můžeme použít dva relační operátory s && k zjištění, zda oba vztahy jsou pravdivé. Následující výraz používá tuto techniku k zjištění zda proměnná index leží v zadaných mezích. Je zjištěno, zda index je větší než 0 a současně menší než 10:
    0 < index && index < 10
    V některých případech druhý operand logického operátoru nemusí být vyhodnocen. Předpokládejme výraz:
    ((index < 10) && (pole[index] != -1))
    Jestliže index je větší než 10, pak levý operand && je nepravdivý. Operátor && vrací pravdu, pouze tehdy pokud oba operandy jsou pravdivé. V naší situaci hodnota && je nepravda a to bez ohledu na hodnotu pravého operandu a tedy pravý operand není vyhodnocován (není tedy např. použit prvek pole, který již do pole nepatří).
    Logické operátory jsou popsány v následující tabulce.
    Operátor
    Použití
    Je pravdivé, když
    &&
    operand1 && operand2
    oba operandy jsou pravdivé
    ||
    operand1 || operand2
    alespoň jeden operand je pravdivý
    !
     ! operand
    operand je nepravdivý
    V C existuje ještě podmíněný operátor ? :. Je to terciální operátor tvaru:
    výraz ? operand1 : operand2
    Operátor vyhodnotí výraz a v případě pravdy vrací operand1 a v případě nepravdy operand2.
  9. Operátory bitových logických operací. Tyto operátory provádějí bitové operace s daty. Operátory jsou popsány v následující tabulce:
  10. Operátor
    Použití
    Operace
    >>
    operand1 >> operand2
    Posouvá bity operandu1 o počet bitů určených operandem2 doprava
    <<
    operand1 << operand2
    Posouvá bity operandu1 o počet bitů určených operandem2 doleva
    &
    operand1 & operand2
    bitový součin
    |
    operand1 | operand2
    bitový součet
    ^
    operand1 ^ operand2
    bitová nonekvivalence
    Oba operátory posunu pouze posouvají bity v levém operandu o počet míst určených pravým operandem. Posuv se provádí ve směru určeném operátorem. Např. následující příkaz posouvá bity v čísle 13 doprava o jednu pozici:
    13 >> 1;
    Binární reprezentace čísla 13 je 1101. Výsledek operace posuvu je 1101 posunuté o jedno místo vpravo, tj. 110 nebo 6 v desítkové soustavě. Nejpravější bit je ztracen. Posun vpravo o jednu pozici je efektivnější než dělení 2. Posun vlevo o jednu pozici je roven násobení 2.
    V následující tabulce jsou uvedeny hodnoty bitového logického součinu:
    operand1
    operand2
    výsledek
    0
    0
    0
    0
    1
    0
    1
    0
    0
    1
    1
    1
    Bitový logický součin provádí logický součin s každou dvojicí odpovídajících bitů v obou operandech. Logický součin nastavuje výsledný bit na 1, jestliže oba operandy jsou 1. Předpokládejme bitový logický součet hodnot 12 a 13, tedy:
    12 & 13
    Výsledek této operace je 12. Binární reprezentace 12 je 1100 a binární reprezentace 13 je 1101. Nejméně významné bity v obou operandech jsou 1 a 0. Výsledný bit je tedy 0. Další bity operandů jsou oba nulové a výsledný bit je tedy 0, atd. Dostaneme tedy:
      1101
    & 1100
    -------
      1100
    Operátor | provádí bitový logický součet. Postupujeme obdobně, ale řídíme se následující tabulkou.
    operand1
    operand2
    výsledek
    0
    0
    0
    0
    1
    1
    1
    0
    1
    1
    1
    1
    Poslední operace je operace nonekvivalence. Zde používáme další tabulku.
    operand1
    operand2
    výsledek
    0
    0
    0
    0
    1
    1
    1
    0
    1
    1
    1
    0
    Tyto bitové logické operace jsou užitečné při práci s množinou logických příznaků. Předpokládejme např. že máme ve svém programu několik logických příznaků, které indikují stav některé komponenty: je viditelná, je přetažitelná, atd. Lépe než definovat několik logických proměnných pro uložení jednotlivých příznaků, můžeme definovat jednu proměnnou a všechny příznaky do ní umístit. Každý bit v této proměnné odpovídá jednomu příznaku a reprezentuje jeho současný stav. Bitové logické operace můžeme použít k nastavování a zjišťování jednotlivých příznaků.
    Nejprve nastavíme konstanty, které indikují příznaky našeho programu. Tyto konstanty jsou mocniny čísla 2 a určují jednotlivé bity příznakové proměnné. Dále definujeme příznakovou proměnnou. Následující kód inicializuje tuto proměnnou na 0, což znamená, že všechny příznaky jsou vynulovány.
    const int VIDITELNE = 1;
    const int PRETAZITELNE = 2;
    const int VYBIRATELNE = 4;
    const int EDITOVATELNE = 8;
    ...
    int priznaky = 0;
    K nastavení příznaku VIDITELNE můžeme použít příkaz
    priznaky = priznaky | VIDITELNE;
    K testování viditelnosti zapíšeme
    priznaky & VIDITELNE
  11. Přiřazovací operátory. Základní přiřazovací operátor = můžeme použít pro přiřazení jedné hodnoty jedné proměnné. Např. k inicializaci proměnné pocet použijeme příkaz:

  12. int pocet = 0;
    C také poskytuje několik složených přiřazovacích operátorů, které umožňují provést aritmetickou, logickou nebo bitovou operaci a přiřazovací operaci jediným operátorem. Předpokládejme, že chceme přičíst k nějaké proměnné číslo a výsledek vložit zpět do této proměnné. To můžeme provést příkazem:
    i = i + 2;
    Můžeme také pro provedení tohoto příkazu použít operátor += a to takto:
    i += 2;
    Oba předchozí řádky kódu jsou ekvivalentní. Další tabulka obsahuje tyto přiřazovací operátory:
    Operátor
    Použití
    Odpovídá
    +=
    op1 += op2
    op1 = op1 + op2
    -=
    op1 -= op2
    op1 = op1 - op2
    *=
    op1 *= op2
    op1 = op1 * op2
    /=
    op1 /= op2
    op1 = op1 / op2
    %=
    op1 %= op2
    op1 = op1 % op2
     &=
    op1 &= op2 
    op1 = op1 & op2 
     |=
     op1 |= op2 
    op1 = op1 | op2 
     ^=
    op1 ^= op2
    op1 = op1 ^ op2 
    <<=
     op1 <<= op2 
    op1 = op1 << op2 
     >>=
    op1 >>= op2 
      op1 = op1 >> op2 

  1. Přejdeme opět k programování. Máme vytvořit konsolovou aplikaci pro převod časového údaje v sekundách na minuty a sekundy. Např. 125 sekund = 2 minuty a 5 sekund. Program může být tvořen těmito příkazy:

  2. int sekundy, minuty;
    cout << "Zadej počet sekund: ";
    cin >> sekundy;
    minuty = sekundy / 60;
    sekundy %= 60;
    cout << minuty << " minut a " << sekundy << " sekund" << endl;
    Vyzkoušejte tento program.
  3. Rozšiřte předchozí program tak, aby zjišťoval i celý počet hodin. Např. 7645 sekund = 2 hodiny, 7 minut a 25 sekund.

Kontrolní otázky:

  1. Jaký je rozdíl mezi aplikací GUI a konzolovou aplikací?
  2. Můžeme přiřadit číselnou konstantu s desetinnou částí do proměnné celočíselného datového typu?
  3. Jakou hodnotu proměnná získá, když ji deklarujeme?
  4. Kolik volání funkcí main může mít program?

Řešení

4. Operátory