Barninga Z
a- a+

Le unioni

ENTITA' COMPLESSE 

Le unioni 

Da quanto detto circa le strutture, appare evidente come essecostituiscano uno strumento per la rappresentazione direaltà complesse, in quanto sono in grado diraggrupparne i molteplici  aspetti quantitativi[43]. Inparticolare, ogni singolo campo di una struttura permette digestire uno degli aspetti che, insieme, descrivonol'oggetto reale. 

Il concetto di unione deriva direttamente da quello distruttura, ma con una importante differenza: i campi di unaunion rappresentano diversi modi di vedere, omeglio, rappresentare, l'oggetto che la unionstessa descrive. Consideriamo l'esempio seguente: 

struct FarPtrWords {    unsigned offset;    unsigned segment;};union Far_c_Ptr {    char far *ptr;    struct FarPtrWords words;};

La dichiarazione di un template di union èdel tutto analoga a quella di un template di struttura:l'unica differenza è costituita dalla presenzadella parola chiave union in luogo distruct

La differenza è però enorme a livelloconcettuale: la struct FarPtrWords comprende duecampi, entrambi di tipo unsigned int. Non ci vuolemolto a capire che essa occupa 4 byte e descrive un puntatoredi tipo "non near" , scomposto nelle duecomponenti di  indirizzo[44]. 

I due campi della union Far_c_Ptr, invece, sonorispettivamente un puntatore a 32 bit e una structFarPtrWords. Contrariamente a quanto ci si potrebbeaspettare, la union non occupa 8 byte, bensìsolo 4: puntatore e struct FarPtrWords sono due modialternativi di interpretarli o, in altre parole, di accedereal loro contenuto. La union Far_c_Ptrè un comodo strumento per gestire un puntatore cometale, o nelle sue parti offset e segmento, a seconda dellanecessità. L'area di memoria in cui il dato sitrova è sempre la stessa, ma il campo ptr lareferenzia come un tutt'uno, mentre la strutturaFarPtrWord consente di accedere ai primi due byte oagli ultimi due, separatamente. 

Si può pensare ad una union come ad uninsieme di "maschere" attraverso le qualiinterpretare il contenuto di un'area dimemoria. 

Vediamo la sintassi, senza preoccuparci dell'espressione(char far *): si tratta di un cast e nonriguarda in modo diretto l'argomento"union": 

union FarPtr fp;  fp.ptr = (char far *)0xB8000000L;    printf("ptr: %Fp" ,fp.ptr);    printf("ptr: %X:%X" ,fp.words.segment,fp.words.offset);

L'accesso ai membri di una union segue lemedesime regole dell'accesso ai membri di unastruct, cioè mediante l'operatore punto(o l'operatore "freccia" se si lavora con unpuntatore). E' interessante notare che inizializzando ilcampo ptr viene inizializzato anche il campoword, in quanto condividono la stessa memoriafisica. Il medesimo campo ptr è poiutilizzato per ricavare il valore del puntatore, mentre ilcampo words consente di accedere alle componentisegment ed offset. Entrambe leprintf() visualizzano 

B800:0000

 

Se nel codice dell'esempio si sostituisce la riga diinizializzazione del campo ptr con le righeseguenti: 

fp.words.offset = 0;    fp.words.segment = 0xB800;

le due printf() visualizzano ancora il medesimooutput. 

La sintassi che consente di accedere ai due campi dellastruct FarPtrWords, a prima vista, puòapparire strana, ma in realtà essa èperfettamente coerente con le regole esposte con riferimentoalle strutture: dal momento che ai campi di unaunion si accede mediante l'operatore punto, sonogiustificate le scritture fp.ptr e fp.wordsma l'operatore punto si utilizza anche per accedere aimembri di una struttura, perciò sono lecite lescritture word.offset e word.segment;ciò spiega fp.word.offset efp.word.segment

Nell'esempio di union analizzato, i membri sonodue ed hanno uguale dimensione (entrambi 4 byte). Vaprecisato che i membri di una union possono esserepiù di due; inoltre essi possono essere di dimensionidifferenti l'uno dall'altro, nel qual caso ilcompilatore, allocando la union, le riserva unaquantità di memoria sufficiente a contenere ilpiù "ingombrante" dei suoi membri, e li"sovrappone" a partire dall'iniziodell'area di memoria occupata dalla unionstessa. Esempio: 

union Far_c_Ptr {    char far *ptr;    struct FarPtrWords words;    unsigned pOffset;}

Il terzo elemento della union è ununsigned int, e come tale occupa 2 byte. Questicoincidono con i primi due byte di ptr (e dellastruct), e rappresentano pertanto la word offset delpuntatore rappresentato dalla union

I puntatori a union si comportano esattamente comei puntatori a struct

 



Ti potrebbe interessare anche

commenta la notizia