5. Pointer na void, pretypovanie
5.2 Pretypovanie (casting)
Možno vás prekvapilo, čo znamená to záhadné (char*) pred pointerom ptr vo funkcii nuluj v predchádzajúcom príklade. Ide o tzv. pretypovanie (casting alebo typecasting),
ktorým môže programátor zabezpečiť konverziu (zmenu) jedného údajového
typu na iný. S pretypovaním ste sa už pravdepodobne stretli, aj
keď nie v kontexte s ukazovateľmi:
char a;
int b;
b = 80;
a = b;
V uvedenom kóde najskôr priradíme do premennej b hodnotu 80 a následne uložíme obsah premennej b do premennej a . Premenná a je ale typu char, zatiaľ čo b je typu int! Toto však nie je problém a to vďaka implicitnému pretypovaniu,
čo vlastne znamená, že počítač "vie", čo chcete urobiť a automaticky
zkonvertuje príslušnú hodnotu z typu int na char bez toho, aby ste
o to museli požiadať.
Príkladom implicitného
pretypovania môže byť teda vyhodnocovanie výrazov, kde operandy jednej
operácie nie sú rovnakého typu alebo typ výsledku je iný ako premenná
na ľavej strane príkazu priradenia. Takéto pretypovanie samozrejme
prebieha podľa presných pravidiel. Ale aj keď sa uskutočňuje
automaticky, neznamená to, že nie je potrebné o ňom nič vedieť. Niekedy
môže byť totiž príčinou zvláštneho správania sa programu práve nechcená
typová konverzia.
Zvláštny zápis z funkcie nuluj je príkladom tzv. explicitného pretypovania t.j. takého, o ktoré žiada sám programátor. V našom príklade sme požadovali, aby sa s pointerom ptr
pracovalo ako s pointerom na typ char. Nový typ (pointer na char)
sme preto uviedli v zátvorkách pred ukazovateľ ptr ako (char*)ptr . Teraz už môžeme použiť operátor dereferencie a nastaviť hodnotu v pamäti na 0:
*(char*)ptr = 0;
Bolo toto pretypovanie skutočne nutné? Prečo sme nemohli napísať *ptr = 0;
? Jednoducho preto, že takýto príkaz by pre počítač nedával žiadny
zmysel. Pre počítač je ptr len nejaká adresa v pamäti, ako má "vedieť"
na koľko bajtov tento pointer ukazuje? V našom prípade sme chceli
vynulovať každý bajt úseku pamäte, preto sme pointer ptr museli
pretypovať na pointer na údajový typ, ktorého veľkosť je práve 1 bajt.
Keďže takým typom je char, pretypovali sme void* na char* . Štandardnou situáciou, kde sa bez konverzie pointerov nezaobídeme je dynamické pridelovanie pamäti.
Explicitné
pretypovanie sa najčastejšie používa pri práci s pointermi, ale
môže sa hodiť aj v iných situáciách. Napr. ak c je premenná
typu char, i je typu int a f je premenná typu double, tak
potom výraz
(int) c znamená prevod znaku na ordinálne číslo, (char) i zase prevod ordinálneho čísla na znak, (int) f znamená "odrezanie" desatinnej časti a pod.
Iným
príkladom, kedy je vhodné použiť explicitnú konverziu typov je
pretypovanie skutočného parametra vo volaní funkcie. Napr. ak voláme
funkciu
double vypocet(double x)
so skutočným parametrom typu int, napíšeme
f = vypocet((double) i);
Vyhneme sa tak varovným hláseniam o nevhodnom type parametra, navyše je hneď jasný úmysel programátora.
|