next up previous contents
Elõre: Mutatók és tömbök Fel: Struktúrák és unionok Vissza: A bitmezõk

A union fogalma

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!


next up previous contents
Elõre: Mutatók és tömbök Fel: Struktúrák és unionok Vissza: A bitmezõk