Egyes feladatok megoldása során felmerülhet annak igénye, hogy ugyanazt a tárterületet különbözõ idõpontokban különbözõ típussal vagy jelleggel értelmezzük és használjuk. Vegyük például egy bináris fa felépítésénél használható adatstruktúrát:
struct fa {
unsigned jelzo_1 : 1,
jelzo_2 : 2,
jelzo_3 : 2;
long info;
struct fa *jobb,
*bal;
};
Minden csomópontnak tartalmaznia kell a leszármazottaira
mutató pointereket. A leveleket (vég-csomópontokat)
arról lehet felismerni, hogy mindkét leszármazottuk
hiányzik, tehát a jobb- és baloldali mutatók
speciális, "nem használt" jelzést adó értékkel
vannak feltöltve (ami, mint látni fogjuk majd, a NULL
érték). A levelekre általában jellemzõ,
hogy a többi csomóponthoz képest további információt
hordoznak. Ilymódon a fenti adatstruktúra a levelek számára
nem megfelelõ, mert ezt a többletadatot nem képes hordozni.
Viszont, ha egy fa új elemmel bõvül, akkor valamelyik
korábbi levél elágaztató csomóponttá
válhat. Nehézkes lenne ehhez megváltoztatni típusát
és ezzel együtt méretét. Most vehetjük hasznát
annak, hogy a leveleknek nincs utódjuk, tehát a bal és
a jobb pointer együtt - 32 vagy 64 biten - hordozza azt az egybites
információt, hogy ez egy levél. Ha felveszünk
a meglévõ bitmezõk közé egy újabbat,
akkor felszabadíthatnánk a két mutató helyét
a pótlólagos információ számára,
csak a fordítót kell értesíteni róla,
hogy ilyenkor ezeket más módon kívánjuk értelmezni.
Erre szolgál a union. Példánkat segítségével
ilyen formába írhatjuk:
struct fa {
unsigned jelzo_1 : 1,
jelzo_2 : 2,
jelzo_3 : 2,
level : 1;
long info;
union {
struct {
struct fa *jobb,
*bal;
} utodok;
long levelinfo;
} u;
};
A fenti felírás azt jelenti a fordítóprogram
számára, hogy az u-val jelölt adatterület
kétféleképpen is használható: vagy két
pointert kell ezen a helyen tárolni az utodok megnevezés
alatt, vagy egy hosszú egész értéket levelinfo
néven. Ezért a fordító az u típusú
adatok tárolásához akkora helyet választ, amekkora
garantáltan elegendõ ahhoz, hogy mindkét rész-típust
külön-külön (de nem egyszerre) be tudja fogadni (A
BORLANDC++ near mutatók esetén 2*2, far
pointereknél 2*4 byte-ot fog lefoglalni). Ha csp típusa
a fenti struktúra, akkor levél esetén írható
például a következõ értékadás:
csp.u.levelinfo = k;míg ha a levélbõl csomópont lett
csp.u.utodok.bal = utod;feltéve, hogy k hosszú egész, utod pedig a fenti struktúrájú adatra mutató pointer. A union-ok definíciója és használata formailag teljesen megegyezik a struktúrákkal, csak azt kell figyelembe venni, hogy struktúrákat a felsorolt elemek egyszerre, együttesen alkotják, míg a union-okban egyidõben a felsorolt elemek közül csak egy számára van hely. Fontos, hogy mindig a programozó felelõssége, hogy egy union-t mindig a benne aktuálisan tárolt adat típusának megfelelõ módon használjon!