Condividi tramite


Campi di bit C

Oltre ai dichiaratori per i membri di una struttura o di un'unione, un dichiaratore di struttura può anche essere un numero specificato di bit, denominato "campo di bit". La sua lunghezza viene impostata dall'dichiaratore per il nome del campo da due punti. Un campo di bit viene interpretato come un tipo integrale.

Sintassi

struct-declarator:
declarator
type-specifierdeclaratoroptare : constant-expression

constant-expression Specifica la larghezza del campo in bit. L'oggetto type-specifier declarator per deve essere unsigned int, signed into inte deve constant-expression essere un valore intero non negativo. Se il valore è zero, la dichiarazione non ha un elemento declarator. Non sono consentite matrici di campi di bit, puntatori a campi di bit e funzioni che restituiscono campi di bit. L'elemento declarator facoltativo assegna il nome al campo di bit. I campi di bit possono essere dichiarati come parte di una struttura. L'operatore address-of (&) non può essere applicato ai componenti del campo di bit.

Non è possibile fare riferimento ai campi di bit senza nome e il relativo contenuto in fase di esecuzione è imprevedibile. I campi di bit possono essere utilizzati come campi fittizi per scopi di allineamento. Un campo di bit senza nome la cui lunghezza specificata è 0 garantisce che l'archiviazione per il membro successivo in struct-declaration-list inizi su un limite int.

Il numero di bit in un campo di bit deve essere minore o uguale alla dimensione del tipo sottostante. Ad esempio, queste due istruzioni non sono legali:

short a:17;        /* Illegal! */
int long y:33;     /* Illegal! */

Questo esempio definisce una matrice bidimensionale di strutture denominata screen.

struct
{
    unsigned short icon : 8;
    unsigned short color : 4;
    unsigned short underline : 1;
    unsigned short blink : 1;
} screen[25][80];

La matrice contiene 2.000 elementi. Ogni elemento è un struttura individuale contenente quattro membri di tipo campo di bit: icon, color, underline e blink. La dimensione di ogni struttura è di 2 byte.

I campi di bit hanno la stessa semantica dei tipi interi. Un campo di bit viene usato nelle espressioni esattamente come una variabile dello stesso tipo di base. Non importa quanti bit si trovano nel campo di bit.

Sezione specifica Microsoft

I campi di bit definiti come int vengono considerati come signed. Un'estensione Microsoft allo standard ANSI C consente char i tipi e long (entrambi signed e unsigned) per i campi di bit. I campi di bit senza nome con tipo base long, shorto (signed o unsignedchar ) forzano l'allineamento a un limite appropriato al tipo di base.

I campi di bit sono allocati in un Integer dal bit meno significativo a quello più significativo. Nel codice riportato di seguito

struct mybitfields
{
    unsigned short a : 4;
    unsigned short b : 5;
    unsigned short c : 7;
} test;

int main( void )
{
    test.a = 2;
    test.b = 31;
    test.c = 0;
    return 0;
}

i bit di test verrebbero disposti nel modo seguente:

00000001 11110010
cccccccb bbbbaaaa

Poiché la famiglia di processori 8086 archivia il byte basso di valori integer prima del byte elevato, l'intero 0x01F2 verrebbe archiviato nella memoria fisica come 0xF2 seguito da 0x01.

Lo standard ISO C99 consente a un'implementazione di scegliere se un campo di bit può allontanarsi tra due istanze di archiviazione. Si consideri questa struttura, che archivia i campi di bit che totali di 64 bit:

struct
{
    unsigned int first : 9;
    unsigned int second : 7;
    unsigned int may_straddle : 30;
    unsigned int last : 18;
} tricky_bits;

Un'implementazione C standard potrebbe comprimere questi campi di bit in due interi a 32 bit. Potrebbe archiviare tricky_bits.may_straddle come 16 bit in un intero a 32 bit e 14 bit nell'intero a 32 bit successivo. La convenzione di Windows ABI raggruppa i campi di bit in numeri interi di archiviazione singoli e non raggruppa le unità di archiviazione. Il compilatore Microsoft archivia ogni campo di bit nell'esempio precedente in modo che si adatti completamente a un intero a 32 bit. In questo caso, first e second vengono archiviati in un intero, may_straddle vengono archiviati in un secondo intero e last vengono archiviati in un terzo intero. L'operatore sizeof restituisce 12 in un'istanza di tricky_bits. Per altre informazioni, vedere Riempimento e allineamento dei membri della struttura.

Fine sezione specifica Microsoft

Vedi anche

Dichiarazioni di struttura