Podmienky alebo rozhodnutia

Bez toho, aby sa program vedel rozhodovať, by sme ďaleko nezašli. Vo väčších aplikáciach je dôležité interagovať s užívateľom ­— ak užívateľ stlačí toto tlačidlo, spravím toto, inak nerobím nič a podobne.

V našich programoch môžeme chcieť, aby sa program správal odlišne, keď je v nejakej premennej párne číslo a odlišne, keď je tam nepárne.

Na rozhodovanie v jazyku C++ slúži príkaz if (po slovensky 'ak') so syntaxou if (<podmienka>) <príkaz-t> alebo if (<podmienka>) <príkaz-t> else <príkaz-f> ('else' = 'inak'). Jeho správanie je veľmi intuitívne, pokiaľ je <podmienka> pravdivá, vykoná sa <príkaz-t>. Pokiaľ je podmienka nepravdivá, tak vykoná to, čo je za else alebo sa nevykoná nič, ak tam slovíčko else nie je.

Príklady použitia:

int x = 1;

if (x == 7)
    printf("x je sedem\n");
else
    printf("x nie je sedem\n");

if (x > 0)
    printf("x je kladne cislo\n");

if (x > 0)
    if (x < 2)
        printf("x je jedna\n");

Pokiaľ chceme vykonať viac príkazov, stačí miesto <príkaz> napísať { <príkaz-1>; <príkaz-2>; ... <príkaz-n>; } takto:

int x = 1;
if (x != 7) {
    printf("x nie je sedem\n");
    x = 7;
    printf("preto som zmenil x na sedem\n");
} else {
    printf("x nie je sedem\n");
    printf("takze nemusim nic robit\n");
}

Čo všetko môže byť podmienka? Podmienkou môže byť ľubovoľný výraz, ktorý má hodnotu typu bool (v prípade, že výraz nevracia hodnotu typu bool, pretypuje sa). Keď má výraz hodnotu true, považujeme ho za pravdivý, false je nepravdivý.

Poznáme mnoho operátorov, ktoré vracajú true/false.

Napríklad ==, !=, <=, >=, < a > patria medzi binárne operátory (t.j. dávame ich medzi dva výrazy, napr. (a + 7) <= (b * 2)). Správanie je opäť intuitívne, a < b je true vtedy, keď a je menej ako b. != znamená nerovná sa, čiže a != 0 vráti true, keď a nie je 0. Pozor, nesmieme si zameniť a == b a a = b. Prvé z toho je výraz, ktorý vráti true, v prípade, že a má rovnakú hodnotu ako b. Druhá vec je normálne priradenie, takže do a vloží hodnotu b-čka, a následne vráti novú hodnotu a. Preto if (a = 7) vráti true bez ohľadu na pôvodnú hodnotu a a navyše zmení hodnotu a na sedem. Na toto si treba dávať fakt veľký pozor.

Potom poznáme aj logické operátory, && (a zároveň), || (alebo) a ! (nie je pravda, že). Ktoré sa správajú opäť intuitívne.
(a == 7) && (b < 3) je true práve vtedy, keď a má hodnotu 7 a b je menej ako 3. (a == 3) || (b < 7) je pravda, keď platí aspoň jedna z podmienok (a == 3), (b < 7). ! robí z false true a z true false, takže napr. !(a < 3) je ekvivalentné s a >= 3. Zaujímavé je, že || a && sa správajú šetrne, napríklad ak máme a || b a vieme, že a je true, tak nemusíme vyhodnocovať b ('pravda alebo hocičo' je stále pravda). A v C++ sa to teda ani vyhodnocovať nebude. Preto zatiaľ čo (true && a = 5) a (false || a = 5) zmenia hodnotu a na 5, (false && a = 5) a (true || a = 5) ju nechajú na pokoji (príkaz a = 5 sa nevykoná).

Tiež si netreba mýliť && s &(bitwise and) a || s |(bitwise or). Dvojité verzie pracujú s bool-mi, teda najprv sa pokúsia pretypovať operandy na booly a potom vyrobia nový bool. (10 || 6) je true. Jednoité verzie rozbijú číslo na bity, s každým bitom spravia operáciu zvlášť (0 = false, 1 = true) a výsledné bity poskladajú naspať do čísla. $(10 | 6) = (1010_2 | 110_2) = 1110_2 = 14$. Bitová verzia ! je ~.

Treba si dávať pozor na prioritu (precedenciu) operátorov (tak ako násobenie má prednosť pri sčítaní, aj ostatné operátory majú medzi sebou nejakú hierarchiu). A aby toho nebolo málo, niektoré veci sa vyhodnocujú sprava doľava a niektoré zľava doprava. Kompletný prehľad nájdete napríklad na tu. Dôležité je, že ak si nie ste istí, tak zátvorkujte, inak sa to správa relatívne rozumne.

Cvičenie: Akú pravdivostnú hodnotu má výraz ((!7 == false) && (0 | (a = 5)) <= 4 )?

Riešenie `( (!7 == false) && (0 | (a = 5)) <= 4 )` $\rightarrow$ `( ( false == false) && (0 | 5) <= 4 )` $\rightarrow$ `( ( true ) && (5) <= 4 )` $\rightarrow$ `( true && false )` $\rightarrow$ `false`

Cvičenie: Akú hodnotu má ((23 | 32) & 30)?

Riešenie $((23 | 32) \& 30) = ((10111_2 | 100000_2) \& 11110_2) = (110111_2 \& 11110_2) = 10110_2 = 22$