41
ROZDZIAŁ 8. OPERATORY
Zadaniem rzutowania jest konwersja danej je<lnego typu na daną innego typu. Konwersja może być niejawna (domyślna konwersja przyjęt a przez kompilator) lub jawna (podana explicite przez programistę). Oto kilka przykładów konwersji niejawnej:
int i - 42.7; float f ■ i; double d ■ f; unsigned u = i; f - 4.2; i-d;
char *str = "foo"; const char *cstr - str; void *ptr - str;
/* konwersja z double do int */
/* konwersja z int do float */
/* konwersja z float do double */
/* konwersja z int do unsigned int */
/* konwersja z double do float */
/* konwersja z double do int */
/* konwersja z const char* do char* [1] */ /* konwersja z char* do const char* •/
/* konwersja z char* do void* */
Podczas konwersji zmiennych zawierających większe ilości danych do typów prost-szych (np. double do int) musimy liczyć się z utratą informacji, jak to miało miejsce w pierwszej linijce zmienna int nie może przechowywać części ułamkowej toteż została ona odcięta i w rezultacie zmiennej została przypisana wartość 12.
Zaskakująca może się wydać linijka oznaczona przez 1. Niejawna konwersja z typu const char* do typu char* nie jest dopuszczana przez standard C. Jednak literały napisowe (które są typu const char*) stanowią tutaj wyjątek. Wynika on z faktu, że były one używane na długo przed wprowadzeniem słówka const do języka i brak wspomnianego wyjątku spowodowałby, że duża część kodu zostałaby nagle zakwalifikowana jako niei>oprawny kod.
Do jawnego wymuszenia konwersji służy jednoarguinentowy operator rzutowania.
np.:
double d - 3.14;
int pi ■ (int)d; /* 1 */
pi = (unsigned)pi » 4; /* 2 */
W pierwszym przypadku operator został użyty, by zwrócić uwagę na utratę precyzji. W drugim, dlatego że bez niego operator przesunięcia bitowego zachowuje się trochę inaczej.
Obie konwersje przedstawione powyżej są dopuszczane przez standard jako jawne konwersje (tj. konwersja z double do int oraz z int do uusigned int). jednak niektóre konwersje są błędne, np.:
const char *cstr = "foo"; char *str ■ estr;
W takich sytuacjach można użyć operatora rzutowania by wymusić konwersję:
const char *cstr - "foo"; char *str ■ (char*)cstr;
Należy unikać jednak takich sytuacji i nigdy nie stosować rzutowania by uciszyć kompilator. Zanim użyjemy operatora rzutowania należy się zastanowić co tak naprawdę będzie on robił i czy nie ma innego sposobu wykonania danej operacji, który nie wymagałby podejmowania tak drastycznych kroków.