Da trilha de C Este conceito ainda não saiu como card do dia. ir para o card de hoje

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 use x &= ~flag.
  • Contar bits ligados: laço com x &= x - 1 remove o bit 1 mais baixo a cada iteração.
bitwise_ops.c
#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;
}

Exercícios

  1. 1
    Fácil

    Verificar bit específico

    Escreva um programa que leia um número inteiro sem sinal e a posição de um bit (0 a 31). Use máscara e shift para verificar se o bit está ligado e imprima 1 se estiver, 0 caso contrário.

    Resolver
  2. 2
    Médio

    Manipular flags de permissão

    Defina três flags: READ (bit 0), WRITE (bit 1) e EXEC (bit 2). Leia comandos do usuário no formato +R, -W, +X até receber 0. Atualize um inteiro flags e, ao final, imprima o valor em hexadecimal e quantas flags estão ligadas.

    Resolver
  3. 3
    Desafio

    Contar bits e inverter nibbles

    Leia um inteiro sem sinal de 32 bits. Conte quantos bits estão ligados (popcount) sem usar funções de biblioteca. Em seguida, inverta a ordem dos quatro nibbles (grupos de 4 bits) e imprima o resultado em hexadecimal. Por fim, imprima o popcount do valor invertido.

    Resolver

Continue estudando