Compartilhar via


Campos de bit C

Além de declaradores para membros de uma estrutura ou união, um declarador de estrutura também pode ser um número especificado de bits, chamado de "campo de bits". Seu comprimento é definido fora do declarador para o nome do campo por dois-pontos. Um campo de bits é interpretado como um tipo integral.

Sintaxe

struct-declarator:
declarator
type-specifier declaratoropt : constant-expression

A constant-expression especifica a largura do campo em bits. O type-specifier de declarator deve ser unsigned int, signed int ou int, e a constant-expression deve ser um valor inteiro não negativo. Se o valor for zero, a declaração não tem nenhum declarator. Matrizes de campos de bits, ponteiros para campos de bits e funções que retornam campos de bits não são permitidos. O declarator opcional nomeia o campo de bits. Os campos de bits só podem ser declarados como parte de uma estrutura. O operador address-of (&) não pode ser aplicado a componentes de campo de bit.

Campos de bits sem nome não podem ser referenciados e o conteúdo em tempo de execução é imprevisível. Podem ser usados como campos “fictícios”, para fins de alinhamento. Um campo de bits sem nome cuja largura for especificada como 0 garante que o armazenamento para o membro após struct-declaration-list comece em um limite int.

O número de bits em um campo de bits deve ser menor ou igual ao tamanho do tipo subjacente. Por exemplo, estas duas instruções não são válidas:

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

Este exemplo define uma matriz de estruturas bidimensional nomeada screen.

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

A matriz contém 2.000 elementos. Cada elemento é uma estrutura individual que contém quatro membros de campo de bits: icon, color, underline e blink. O tamanho de cada estrutura é de 2 bytes.

Os campos de bits têm a mesma semântica do tipo inteiro. Um campo de bit é usado em expressões exatamente da mesma forma que uma variável do mesmo tipo base seria usada. Não importa quantos bits há no campo de bit.

Seção específica da Microsoft

Os campos de bits definidos como int são tratados como signed. Uma extensão da Microsoft para o padrão ANSI C permite tipos char e long (signed e unsigned) para campos de bits. Os campos de bits sem nome com o tipo de base long, short ou char (signed ou unsigned) forçam o alinhamento a um limite adequado para o tipo de base.

Os campos de bit são alocados em um inteiro do bit menos significativo ao bit mais significativo. No código a seguir

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

os bits de test seriam organizados da seguinte maneira:

00000001 11110010
cccccccb bbbbaaaa

Como a família de processadores 8086 armazena o byte baixo de valores inteiros antes do byte alto, o inteiro 0x01F2 seria armazenado na memória física como 0xF2 seguido por 0x01.

O padrão ISO C99 permite que uma implementação escolha se um campo de bits pode abranger duas instâncias de armazenamento. Considere esta estrutura, que armazena campos de bit, totalizando 64 bits:

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

Uma implementação C padrão poderia empacotar esses campos de bit em dois inteiros de 32 bits. Ela pode armazenar tricky_bits.may_straddle como 16 bits em um inteiro de 32 bits e 14 bits no próximo inteiro de 32 bits. A convenção do Windows ABI empacota campos de bits em inteiros de armazenamento único e não abrange unidades de armazenamento. O compilador da Microsoft armazena os campos de bits no exemplo acima para que ele se ajustem completamente em um inteiro de 32 bits. Nesse caso, first e second são armazenados em um inteiro, may_straddle é armazenado em um segundo inteiro e last é armazenado em um terceiro inteiro. O operador sizeof retorna 12 em uma instância de tricky_bits. Para obter mais informações, consulte Preenchimento e alinhamento de membros da estrutura.

Fim da seção específica da Microsoft

Confira também

Declarações de estrutura