6 STRUKTURY _____________
wyboru odpowiednich spośród typów short, int lub long dla każdej docelowej maszyny. Dobrymi przykładami są typy size_l i ptrdiff_t pochodzące z biblioteki standardowej.
Drugą przyczyną stosowania typedef jest to, że taka deklaracja lepiej komentuje program - typ o nazwie Treeptr można łatwiej zrozumieć niż zadeklarowany wprost jako wskaźnik do skomplikowanej struktury.
Unia jest zmienną, która (w różnych momentach) może zawierać obiekty różnych typów i rozmiarów, przy czym to kompilator dba o zadośćuczynienie wymaganiom dotyczącym rozmiaru i położenia w pamięci. Unie pozwalają manipulować danymi różnego rodzaju w tym samym miejscu pamięci bez wprowadzania do programu informacji o ich cechach zależnych od maszyny. Unie są podobne do rekordów wariantowych w Pascalu.
Jako przykład, który można znaleźć w programie zarządzającym tablicą symboli kompilatora, przypuśćmy, że stała może być typu int, float lub wskaźnikiem znakowym. Wartość konkretnej stałej należy zapamiętać w zmiennej o właściwym typie, jednakże dla obsługi tablicy najwygodniej jest, aby każda taka wartość zajmowała obszar tej samej wielkości i (niezależnie od jej typu) była wstawiana w to samo miejsce pamięci. Taki jest właśnie cel unii - udostępnić jedną zmienną, która jest uprawniona do przechowywania wartości kilku różnych typów. Składnia unii jest wzorowana na strukturach:
union u_Jag { int ival; float fval; char *sval;
1 i
Zmienna u będzie wystarczająco obszerna, aby pomieścić w sobie wartość najwięk-szego z tych trzech typów; właściwy rozmiar zależy od implementacji. Zmiennej u można przypisać wartość każdego z tych typów, a następnie używać jej w wyrażeniach dopóty, dopóki użycie to jest prawidłowe: typ wartości pobieranej musi być typem tej wartości, która została ostatnio przypisana. Do programisty należy kontrola typu obiektu aktualnie znajdującego się w unii; jeśli coś zostanie zapamiętane z jednym typem, a pobrane z innym, to wynik zależy od implementacji.
6.8 UNIE
Postać odwołania do składowych unii jest następująca:
nazw a-unii. składowa lub
wskaźnik-do-unii->składowa
czyli identyczna, jak dla struktur. Jeżeli zmienna utype służy do kontroli typu wartości zmiennej u, to możemy się spotkać na przykład z takim fragmentem programu:
if (utype == INT) printf(”%d\n”, u.ival); else if (utype == FLOAT) printf(”%f\n”, u.fval); else if (utype == STRING) printf(”%s\n”, u.sval); else
printffzły typ %d w utype\n”, utype);
Unie mogą występować w strukturach i tablicach, i vice versa. Notacja dla odwołania do składowej unii w strukturze (lub odwrotnie) jest taka sama, jak dla zagnieżdżonych struktur. Na przykład dla tablicy struktur:
struct {
char *name; int flags; int utype; union { int ival; float fval; char *sval; } u;
} symtab[NSYM];
/* nazwa symbolu */ /* znaczniki stanu */ I* typ wartości */
/* wartość */
I* tablica symboli */
odwołanie do składowej ival ma postać symtab[i].u.ival
a odwołanie do pierwszego znaku tekstu wskazywanego przez sval można zapisać na dwa równoważne sposoby
*symtab[i].u.sval
symtab[i].u.sval[0)
199