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