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.