C Fundamentos Avançado
Operações bit a bit
Operações bit a bit manipulam diretamente os bits de inteiros usando operadores como &, |, ^, ~, << e >>. Elas são essenciais para programação de baixo nível, otimização e representação compacta de dados.
Uma máscara é um valor usado para isolar, ligar ou desligar bits específicos. Por exemplo, x & 0x0F mantém apenas os 4 bits menos significativos de x. Já x | 0x80 liga o bit 7.
Shifts movem bits para a esquerda (<<) ou direita (>>). x << n equivale a multiplicar por 2^n, enquanto x >> n divide por 2^n (para inteiros sem sinal).
Flags são bits individuais que representam estados booleanos, frequentemente combinados com | e testados com &. Contar bits ligados (popcount) pode ser feito com um laço simples ou com truques como x &= x - 1.
Pontos-chave
&(AND),|(OR),^(XOR) e~(NOT) operam bit a bit.- Máscaras isolam ou modificam bits específicos:
x & mask,x | mask,x ^ mask. <<e>>deslocam bits; cuidado com overflow e comportamento de shift à direita para negativos.- Flags são combinadas com
|e testadas com&; para limpar bits usex &= ~flag. - Contar bits ligados: laço com
x &= x - 1remove o bit 1 mais baixo a cada iteração.
#include <stdio.h>
// Conta bits ligados usando truque x &= x - 1
int count_bits(unsigned int x) {
int count = 0;
while (x) {
x &= x - 1; // remove o bit 1 mais baixo
count++;
}
return count;
}
int main(void) {
unsigned int flags = 0;
const unsigned int READ = 1u << 0; // bit 0
const unsigned int WRITE = 1u << 1; // bit 1
const unsigned int EXEC = 1u << 2; // bit 2
// Liga READ e WRITE
flags |= READ | WRITE;
printf("flags = 0x%X\n", flags);
// Testa se READ está ligado
if (flags & READ) {
printf("READ habilitado\n");
}
// Desliga WRITE
flags &= ~WRITE;
printf("flags apos desligar WRITE = 0x%X\n", flags);
// Conta bits ligados
printf("bits ligados = %d\n", count_bits(flags));
// Shift: extrai nibble alto de 0xAB
unsigned int val = 0xAB;
unsigned int high_nibble = (val >> 4) & 0x0F;
printf("nibble alto de 0xAB = 0x%X\n", high_nibble);
return 0;
}