11. diel - Pretypovania a operátormi
Z matematiky vieme, že násobenie a delenie má prednosť pred sčítaním a odčítaním. To je úplne bežné a očakávali by sme to aj od programovacieho jazyka. Hoci sa tento predpoklad zdá úplne bežný, nemusí nutne platiť. Všetko závisí na určenie jazyka a na tom, ako je jazyk navrhnutý. V C ++ navyše máme vedľa základných aritmetických operácií ďalšie operácie - logické, binárne atď. Schválne či uhádnete, či má prednosť sčítanie alebo modulo? A ako je na tom modulo s násobením? A budú sa operácie vyhodnocovať sprava alebo zľava?
Priority operátorov
Jazyk definuje tzv priority operátorov. Operátor s vyššou prioritou sa vyhodnotí pred operáciou s prioritou nižšou. Nikoho asi neprekvapí, že operácia násobenie má vyššiu prioritu ako operácia sčítanie. V nasledujúcej tabuľke sú zhrnuté všetky operácie a ich priorita (nižšie číslo udáva vyššiu prioritu). Niektoré operátormi ešte nemusíte poznať, to nevadí, pbudou prebrané až v lekcii OOP.
prednosť | operátor | popis | smer vyhodnotenie |
---|---|---|---|
1 | :: |
rozlíšenie kontextu | zľava |
2 | ++ -- |
postfixové operátormi inkrementácia a dekrementace | |
() |
operátor volanie funkcie | ||
[] |
operátor prístupu k prvku poľa | ||
. |
výber členovi cez referenciu | ||
-> |
výber členovi cez ukazovateľ | ||
3 | ++ -- |
prefixové operátormi inkrementácia a dekrementace | sprava |
+ − |
unárne plus a mínus | ||
! ~ |
logická a bitová negácia | ||
(type) |
operátor pretypovanie | ||
`` ** | operátor dereferencia | ||
& |
získanie adresy prvku | ||
sizeof |
veľkosť prvku | ||
new , new[] |
dynamická alokácia pamäte | ||
delete ,
delete[] |
Dynamická delokácia pamäte | ||
4 | . -> ** |
ukazovateľ na člen | zľava |
5 | ` `/ % |
operátormi násobenie, delenie a zvyšok po delení | |
6 | + − |
operátormi súčtu a rozdielu | |
7 | << >> |
bitový posun doľava a doprava | |
8 | < <= |
Relačné operátory <a ≤ | |
> >= |
Relačné operátory> a ≥ | ||
9 | == != |
Relačné operátory = a ≠ | |
10 | & |
bitové AND | |
11 | ^ |
bitové XOR (výlučný súčet) | |
12 | | |
bitové OR | |
13 | && |
logické AND | |
14 | || |
logické OR | |
15 | ?: |
ternárne operátor [1] | sprava |
= |
priame priradenie | ||
+= −= |
priradenie pripočítaním a odpočítaním | ||
*= /= %= |
Priradenie násobením, podielom a zvyškom | ||
<<= >>= |
priradenie bitovým posunom doľava a doprava | ||
&= ^= |= |
priradenie bitovú operácií AND, XOR a OR | ||
16 | throw |
operátor throw (pre výnimky) | |
17 | , |
operátor čiarka | zľava |
Chýba tu jeden dôležitý operátor - zátvorky. Zátvorkách má najvyššiu prioritu a je vždy vyhodnotené pred zvyšnými operáciami. Odporúčam nespoliehať na prioritu operátorov a radšej dávať do vyhodnotenia zátvorky. Nielenže budete mať kontrolu nad vyhodnocovaním operátorov, program sa bude aj oveľa lepšie čítať - hlavne pre ľudí, ktorí prídu po vás.
Pretypovanie
C ++ zavádza pre pretypovanie veľkú veľa pravidiel (ešte viac ako u operátor). Ak by vás zaujímalo viac, môžete si informácie dohľadať v dokumentácii (v angličtine). Tu vypichnem len niekoľko dôležitých konštrukcií, ktoré C používa.
V základe existujú dva typy pretypovanie - explicitné a implicitné. Implicitné pretypovanie je také, ktoré prebieha automaticky. Jedná sa o konverzie z typu o menšom rozsahu hodnôt do schválenia o väčšom rozsahu hodnôt. Graficky si môžeme implicitné konverzie zobraziť ako jednosmerný reťaz, ktorý udáva, ktoré konverzie sú možné.
char unsigned char short unsigned short int <=> enum unsigned int long unsigned long long long unsigned long long float double long double
Typ, ktorý je hore, sa implicitne přetypuje na ľubovoľný typ pod ním, ak je to potrebné.
Obráteným smerom prebieha tzv explicitné konverzie. Kompilátora musíme dodať informáciu, že typ chceme skutočne pretypovať na typ menšie. Ak máme vo väčšom type príliš veľké číslo, menšie typ ho nemusí celej uložiť. Stratíme tým časť informácie - napríklad pri pretypovanie čísla z float do int sa stratí časť čísla za desatinnou čiarkou. Kompilátor chce mať istotu, že sme skutočne operáciu požadovali a nejedná sa o chybu. Pretypovania napíšeme tak, že pred výraz, ktorý chceme pretypovať, napíšeme do zátvorky požadovaný typ. Pre príklad si napíšeme program pre výpočet priemeru.
#include <iostream> using namespace std; int main( int argc, char** argv ) { unsigned int suma = 0; unsigned int pocet = 0; cout << "Zadejte cisla (zaporne cislo pro ukonceni): "; while( true ) { int precteno; cin >> precteno; if( (bool)cin==false || precteno < 0 ) break; suma += precteno; pocet++; } double prumer = (double)suma / (double)pocet; cout << "Prumer je: " << prumer << endl; cin.get(); return 0; }
Najskôr prečítame všetky čísla. Pretože priemer nie je celé číslo, musíme pred samotným delením čísla previesť na typ double - v C ++ vracia delení dvoch celých čísel vždy číslo celé. V tomto prípade by stačilo pretypovať iba jedno číslo (podľa pravidiel C ++), ale je vždy lepšie explicitne povedať, že sa majú previesť čísla obe - program sa lepšie číta. Tiež je v programe použité implicitné pretypovanie, pri pričítanie prečítaného čísla (ktoré je int) k sume (ktorá je unsigned int).
Kam ďalej
Gratulujem, práve ste dokončili pokročilé konštrukcia jazyka C ++. Teraz ste už pripravení na to, aby ste sa začali zaoberať objektovo orientovaným programovaním. Pred samotným OOP ale odporúčam prečítať tri články: Kompilácia v jazyku C a C ++, ďalej Kompilácia v jazyku C a C ++ druhýkrát a nakoniec článok Knižnice v jazyku C a C ++. Povedia vám, ako to všetko vlastne pod kapotou funguje. Teraz už hurá na OOP.