142
ItOZDZIAL 19. TYPY ZŁOŻONE
kierunek ■ W_DOL;
printf("Xi\n", kierunek); /* wypisze 1 •/
Kolejne wartości to |w> prostu liczby naturalne: domyślnie pierwsza to zero. druga jeden itp. Możemy przy deklarowaniu typu wyliczeniowego zmienić domyślne przypor/ądkowanie:
onura Kierunek { W.GORE, W_D0L ■ 8, W.LEWO. W.PRAWO }; printf("Xi Xi\n\ W.DOL, W.LEWO); /• wypisze 89*/
O) więcej liczby mogą się powtarzać i wcale nie muszą być ustawione w kolejności rosnącej:
enum Kierunek { W.GORE - 5, W.DOL - 5. W.LEWO - 2. W.PRAWO ■ 1 >; printf(MXi Xi\n", W.DOL, W.LEWO); /• wypisze 52*/
Traktowanie przez kompilator typu wyliczeniowego jako liczby pozwala na wydajną ich obsługę, ale stwarza niebezpieczeństwa można przypisywać pod typ wyliczeniowy liczby, nawet nie mające odpowiednika w wartościach, a kompilator może o tym nawet nie ostrzec:
kierunek = 40;
Są to twory deklarowane w następujący sposób:
union Nazwa { typl nazwał; typ2 nazwa2;
/* ... */
Na przykład:
union LiczbaLubZnak { int całkowita; char znak; double rzeczywista;
Pola w unii nakładają się na siebie w ten sposób, że w danej chwili można w niej przechowywać wartość tylko jednego typu. Unia zajmuje w pamięci tyle miejsca, ile zajmuje największa z jej składowych. W powyższym przypadku unia będzie miała prawdopodobnie rozmiar typu double czyli często 64 bity, a całkowita i znak będą wskazywały od|x>wicdnio na pierwsze cztery bajty lul) na pierwszy bajt unii (choć nie musi tak być zawsze).
Do konkretnych wartości pól unii odwołujemy się przy pomocy operatorem wyboru składnika kropki:
union LiczbaLubZnak liczba;
liczba.całkowita - 10;
printf("Xd\n", liczba.całkowita);
Zazwyczaj użycie unii ma tui celu zmniejszenie zapotrzebowania na pamięć, gdy naraz będzie wykorzystywane tylko jedno pok* i jest często łączone- z użyciem struktur.
Życiowy przykład użycia — zamieniamy kolejność bajtów w p.pl — np. w kodzie oprogramowania sieciowego Big Endian -> Little Kndian, gdy potrzeba zmiany numeru portu podanego w “nie sieciowej” kolejności bajtów: