Última atualização:2026-10-12
Bit fields em C++¶
Sobre o autor:¶
Conta oficial do WeChat:

O que é um Bit field?¶
Um bit field (campo de bits) é uma estrutura de dados que permite armazenar dados de forma compacta em bits e permite ao programador operar sobre os bits dessa estrutura. Uma vantagem dessa estrutura de dados é que ela economiza espaço de armazenamento por unidade de dados; quando o programa precisa de milhares ou milhões de unidades de dados, esse método se torna especialmente importante. Uma segunda vantagem é que o bit field permite acessar com facilidade partes do conteúdo de um valor inteiro, simplificando o código-fonte do programa. A desvantagem dessa estrutura de dados é que a implementação de bit fields depende da máquina e do sistema concretos, podendo gerar resultados diferentes em plataformas distintas; isso torna os bit fields, em essência, não portáveis.
- A disposição de um bit field na memória depende da máquina
- O tipo de um bit field deve ser inteiro ou de enumeração; o comportamento de bit fields em tipos com sinal varia conforme a implementação
- O operador de endereço (&) não pode ser aplicado a um bit field; nenhum ponteiro pode apontar para um bit field de uma classe
Uso de bit fields¶
Bit fields costumam ser declarados com uma estrutura; a declaração da estrutura define um nome para cada membro bit field e determina a sua largura:
| Elemento | Descrição |
|---|---|
| bit_field_name | nome da estrutura de bit field |
| type | tipo do membro do bit field, deve ser int, signed int ou unsigned int |
| member_name | nome do membro do bit field |
| width | número de bits ocupados pelo membro |
Por exemplo, declare o seguinte bit field:
struct _PRCODE
{
unsigned int code1: 2;
unsigned int cdde2: 2;
unsigned int code3: 8;
};
struct _PRCODE prcode;
Essa definição faz com que prcode contenha 2 bit fields de 2 Bits e 1 bit field de 8 Bits; podemos atribuir valores usando o operador de membro da estrutura
Ao atribuir, atenção para que o valor não exceda a capacidade do membro do bit field; por exemplo, prcode.code3 é um membro de bit field de 8 Bits, cuja capacidade é 2^8 = 256, ou seja, a faixa de valores deve ser [0,255].
Tamanho e alinhamento de bit fields¶
O tamanho de um bit field¶
Por exemplo, o seguinte bit field:
No meio dessa estrutura de bit field há um bit field sem nome, ocupando 3 Bits, que serve apenas de preenchimento, sem significado prático. O preenchimento faz a estrutura usar 8 Bits no total. Mas a linguagem C usa unsigned int como unidade básica do bit field: mesmo que o único membro de uma estrutura seja um bit field de 1 Bit, o tamanho da estrutura é o mesmo de um unsigned int. Em alguns sistemas, unsigned int tem 16 Bits; em sistemas x86, 32 Bits. O restante do artigo assume unsigned int com 32 Bits.
O alinhamento de bit fields¶
Um membro de bit field não pode cruzar a fronteira de dois unsigned int; se o número total de bits declarados dos membros exceder o tamanho de um unsigned int, o compilador desloca automaticamente os membros do bit field para alinhá-los segundo as fronteiras de unsigned int. Por exemplo:
field1 + field2 = 34 Bits, excedendo 32 Bits; o compilador desloca field2 para a próxima unidade de unsigned int, deixando uma lacuna de 2 Bits entre stuff.field1 e stuff.field2; stuff.field3 vem logo após stuff.field2, e a estrutura passa a ter tamanho de 2 * 32 = 64 Bits.
Esse vão pode ser preenchido com o membro de bit field sem nome mencionado antes; também podemos usar um membro de bit field sem nome com largura 0 para forçar o próximo membro a se alinhar com o próximo inteiro. Por exemplo:
struct stuff
{
unsigned int field1: 30;
unsigned int : 2;
unsigned int field2: 4;
unsigned int : 0;
unsigned int field3: 3;
};
Aqui há uma lacuna de 2 Bits entre stuff.field1 e stuff.field2, e stuff.field3 é armazenado no próximo unsigned int; a estrutura passa a ter tamanho de 3 * 32 = 96 Bits.
O código para estudo está em: bit.cpp
Inicialização e remapeamento de bits de bit fields¶
Inicialização¶
A inicialização de um bit field é igual à de uma estrutura comum; listamos aqui duas formas, assim:
Ou atribua valores diretamente aos membros do bit field
Remapeamento de bit fields (Re-mapping)¶
Declare um bit field de tamanho 32 Bits
struct box {
unsigned int ready: 2;
unsigned int error: 2;
unsigned int command: 4;
unsigned int sector_no: 24;
}b1;
Zerar o bit field usando remapeamento¶
Usar uma união (union) para remapear um bit field de 32 Bits para o tipo unsigned int¶
Primeiro, uma breve introdução às uniões
Uma "união" é uma classe especial e também uma estrutura de dados de tipo construído. Dentro de uma "união" podem ser definidos vários tipos de dados diferentes; numa variável declarada como desse tipo "união", é permitido carregar qualquer um dos dados definidos pela "união"; esses dados compartilham o mesmo trecho de memória, com o objetivo de economizar espaço.
A "união" tem algumas semelhanças com a "estrutura", mas as duas são essencialmente diferentes. Numa estrutura, cada membro tem seu próprio espaço de memória, e o comprimento total de uma variável de estrutura é a soma dos comprimentos dos membros (exceto estruturas vazias, e sem considerar ajustes de fronteira). Já na "união", os membros compartilham um trecho de memória, e o comprimento de uma variável de união é igual ao comprimento do maior dos membros. Vale esclarecer que esse compartilhamento não significa carregar vários membros simultaneamente numa variável de união, e sim que a variável de união pode receber o valor de qualquer membro, mas somente um valor por vez; atribuir um novo valor sobrescreve o antigo.
Podemos declarar a seguinte união:
Em sistemas x86, unsigned int e box têm ambos 32 Bits; por meio dessa união, st_box e ui_box compartilham um bloco de memória. Qual bit do bit field corresponde a qual bit do unsigned int depende do compilador e do hardware. Para zerar o bit field usando a união, o código é o seguinte:
Referência de estudo: http://www.yuan-ji.me/C-C-%E4%BD%8D%E5%9F%9F-Bit-fields-%E5%AD%A6%E4%B9%A0%E5%BF%83%E5%BE%97/
Tópicos relacionados¶
- Funções virtuais puras e classes abstratas em C++ | C++那些事
- Asserções com assert em C++ | C++那些事
- Implementando polimorfismo de C++ em linguagem C | C++那些事
- Constantes e modificadores com const em C++ | C++那些事
- A família completa do const em C++ | C++那些事
- O operador de desreferência * em C++ | C++那些事
- Inicialização e atribuição em C++ | C++那些事
- Formas de retornar múltiplos valores em C++ | C++那些事
- A palavra-chave mutable em C++ | C++那些事
- C++ restrict e otimização do compilador | C++那些事