Compartir a través de


Campos de bits de C

Además de declaradores para los miembros de una estructura o unión, un declarador de estructura también puede ser un número de bits especificado, denominado "campo de bits". Su longitud se establece en dos puntos desde el declarador para el nombre del campo. Un campo de bits se interpreta como un tipo entero.

Sintaxis

struct-declarator:
declarator
type-specifierdeclaratoropt:constant-expression

constant-expression especifica el ancho del campo en bits. El valor type-specifier de declarator debe ser unsigned int, signed int o int y el valor de constant-expression debe ser un entero no negativo. Si el valor es cero, la declaración no tiene ningún declarator. No se permiten matrices de campos de bits, punteros a campos de bits ni funciones que devuelvan campos de bits. El declarator opcional asigna el nombre del campo de bits. Los campos de bits solo se pueden declarar como parte de una estructura. No se puede aplicar el operator address-of (&) a los componentes de campos de bits.

No se puede hacer referencia a campos de bits sin nombre y su contenido en tiempo de ejecución es impredecible. Se pueden utilizar como campos "ficticios" para la alineación. Un campo de bits sin nombre cuyo ancho se especifica como 0 garantiza que el almacenamiento para el miembro que hay a continuación en struct-declaration-list empieza en un límite int.

El número de bits de un campo de bits debe ser menor o igual que el tamaño del tipo subyacente. Por ejemplo, estas dos instrucciones no son válidas:

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

En este ejemplo se define una matriz bidimensional de estructuras denominada screen.

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

La matriz contiene 2000 elementos. Cada elemento es una estructura individual que contiene cuatro miembros de campo de bits: icon, color, underline y blink. El tamaño de cada estructura es de dos bytes.

Los campos de bits tienen la misma semántica que el tipo integer. Un campo de bits se utiliza en las expresiones de la misma manera que se usaría una variable del mismo tipo base. No importa cuántos bits hay en el campo de bits.

Específicos de Microsoft

Los campos de bits definidos como int se tratan como signed . Una extensión de Microsoft al estándar ANSI C permite tipos char y long (tanto signed como unsigned ) para campos de bits. Los campos de bits sin nombre con el tipo base long, short o char (signed o unsigned) fuerzan la alineación con un límite adecuado para el tipo base.

Los campos de bits se asignan dentro de un entero del bit menos significativo al bit más significativo. En el código siguiente

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;
}

los bits de test se organizan de esta forma:

00000001 11110010
cccccccb bbbbaaaa

Puesto que la familia de procesadores 8086 almacena el byte bajo de los valores enteros antes que el byte alto, el entero 0x01F2 se almacenaría en la memoria física como 0xF2 seguido de 0x01.

El estándar ISO C99 permite a una implementación elegir si un campo de bits puede estar entre dos instancias de almacenamiento. Tenga en cuenta esta estructura, que almacena campos de bits que suman 64 bits:

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

Una implementación estándar de C podría empaquetar estos campos de bits en dos enteros de 32 bits. Podría almacenar tricky_bits.may_straddle como 16 bits en un entero de 32 bits y 14 bits en el siguiente entero de 32 bits. La convención ABI de Windows empaqueta campos de bits en enteros de almacenamiento únicos y no ocupa unidades de almacenamiento. El compilador de Microsoft almacena cada campo de bits del ejemplo anterior para que se ajuste completamente a un único entero de 32 bits. En este caso, first y second se almacenan en un entero, may_straddle se almacena en un segundo entero y last se almacena en un tercer entero. El operador sizeof devuelve 12 en una instancia de tricky_bits. Para obtener más información, vea Relleno y alineación de miembros de estructura.

FIN de Específicos de Microsoft

Vea también

Declaraciones de estructura