Barninga Z
a- a+

I campi di bit

ENTITA' COMPLESSE 

I campi di bit 

Se una variabile di tipo intero può assumere solo un limitato numero di valori, è teoricamente possibile memorizzarla utilizzando un numero di bit inferiore a quello assegnatole dal compilatore: basta infatti 1 bit per memorizzare un dato che può assumere solo due valori, 2 bit per un dato che può assumere quattro valori, 3 bit per uno che può assumere otto valori, e così via. 

Il C non ha tipi intrinseci di dati con un numero di bit inferiori a 8 (il char), ma consente di "impaccare" più variabili nel numero di bit strettamente necessario mediante i cosiddetti campi di bit. 

Un esempio di uso di questo strumento può essere ricavato con riferimento alla gestione di una cartella clinica. Supponiamo di voler gestire, per ogni paziente, le seguenti informazioni: il sesso (maschile o femminile), lo stato vitale (vivente, defunto, in coma), il tipo di medicinale somministrato (sedici categorie, come antibiotici e sulfamidici), la categoria di ricovero (otto possibili sistemazioni, da corsia a camera di lusso). In questa ipotesi sarebbe possibile codificare il sesso mediante un solo bit, lo stato vitale con 2, il tipo di cura con 4, la sistemazione in ospedale con 3: in totale 10 bit, senz'altro disponibili in un'unica variabile di tipo intero. 

L'uso dei campi di bit prevede la dichiarazione di un template: anche in questo caso la somiglianza con le strutture è palese. 

struct CartellaClinica {
    unsigned sesso: 1;
    unsigned stato: 2;
    unsigned cura: 4;
    unsigned letto: 3;
};

La dichiarazione utilizza la parola chiave struct, proprio come se si trattasse di un template di struttura; le dichiarazioni dei campi sono introdotte da uno specificatore di tipo e chiusa dal punto e virgola; la differenza qui consiste nell'indicazione dell'ampiezza in bit di ogni singolo campo, effettuata posponendo al nome del campo il carattere due punti (":") seguito dal numero di bit da assegnare al campo stesso. I due punti servono, infatti, a indicare la definizione di un campo di bit, la cui ampiezza viene specificata dal numero seguente; se il numero totale di bit non è disponibile in un'unica variabile intera, il compilatore alloca anche la successiva word in memoria. 

I campi di bit del tipo CartellaClinica sono tutti dichiarati unsigned int: in tal modo tutti i bit sono utilizzabili per esprimere i valori che di volta in volta i campi stessi assumeranno. In realtà, i campi di bit possono anche essere dichiarati int, ma in questo caso il loro bit più significativo rappresenta il segno e non è quindi disponibile per memorizzare il valore. Un campo dichiarato int ed ampio un solo bit può esprimere solo i valori 0 e ­1

I campi di bit sono referenziabili esattamente come i campi di una comune struttura: 

enum SEX {
    maschile,
    femminile
};

struct CartellaClinica {
    unsigned sesso: 1;
    unsigned stato: 2;
    unsigned cura: 4;
    unsigned letto: 3;
};

char *sessi[] = {
    "MASCHILE" ,
    "FEMMINILE"
};
....
    struct CartellaClinica Paziente;
    ....
    Paziente.sesso = maschile;
    ....
    printf("Sesso del paziente: %s
" ,sessi[Paziente.sesso]);

E' importante ricordare come sia compito del programmatore assicurarsi che i valori memorizzati nei campi di bit non occupino più bit di quanti ne sono stati loro riservati in fase di definizione del template, dal momento che le regole del C non assicurano che venga effettuato un controllo nelle operazioni di assegnamento di valori ai campi. Se si assegna ad un campo di bit un valore maggiore del massimo previsto per quel campo, può accadere che i bit più significativi di quel valore siano scritti nei campi successivi: è bene, ancora una volta, verificare il comportamento del proprio compilatore. 

Naturalmente un campo di bit può essere utilizzato anche per memorizzare un'informazione di tipo quantitativo: ad esempio, la struct CartellaClinica potrebbe essere ridefinita mediante l'aggiunta di un campo atto a memorizzare il numero di ricoveri subiti dal paziente; impiegando 6 bit tale valore è limitato a 63. 

struct CartellaClinica {
    unsigned sesso: 1;
    unsigned stato: 2;
    unsigned cura: 4;
    unsigned letto: 3;
    unsigned ricoveri: 6;
};

Nella nuova definizione, tutti i 16 bit delle due word occupate in memoria dalla struct CartellaClinica sono utilizzati.

 



Ti potrebbe interessare anche

commenta la notizia

C'è 1 commento
Francesco
Hai dubbi su questo articolo?