Médio C
Manipular flags de permissão
Enunciado
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.
Requisitos
- Usar
|=para ligar e&= ~para desligar flags. - Contar bits ligados com um laço ou truque
x &= x - 1. - Imprimir valor em hexadecimal com
%Xe a contagem.
Código inicial
#include <stdio.h>
int main(void) {
unsigned int flags = 0;
const unsigned int READ = 1u << 0;
const unsigned int WRITE = 1u << 1;
const unsigned int EXEC = 1u << 2;
char op;
char flag;
// leia comandos até '0'
return 0;
}
Saída esperada
flags = 0x5
bits ligados = 2
Ver dica
Leia a operação e a flag com scanf(" %c%c", &op, &flag). Use um switch ou if para escolher a máscara correta.
Mostrar solução
#include <stdio.h>
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;
const unsigned int WRITE = 1u << 1;
const unsigned int EXEC = 1u << 2;
char op, flag;
while (scanf(" %c%c", &op, &flag) == 2) {
if (op == '0') break; // comando de parada
unsigned int mask = 0;
switch (flag) {
case 'R': mask = READ; break;
case 'W': mask = WRITE; break;
case 'X': mask = EXEC; break;
default: continue; // ignora flag inválida
}
if (op == '+') {
flags |= mask; // liga flag
} else if (op == '-') {
flags &= ~mask; // desliga flag
}
}
printf("flags = 0x%X\n", flags);
printf("bits ligados = %d\n", count_bits(flags));
return 0;
}
Passo a passo
- Definimos as flags como potências de dois:
1u << 0,1u << 1,1u << 2. - O laço
whilelê pares de caracteres (operação e flag) até o fim da entrada ou atéop == '0'. - Um
switchmapeia a letra da flag para a máscara correspondente. - Se a operação for
+, usamosflags |= maskpara ligar o bit; se for-, usamosflags &= ~maskpara desligá-lo. - A função
count_bitsusax &= x - 1para apagar o bit 1 mais baixo a cada iteração, contando quantos havia. - No final, imprimimos o valor em hexadecimal e a contagem.
Por que funciona
Flags são representadas por bits independentes. O OR (|=) liga um bit sem afetar os outros; o AND com NOT (&= ~) desliga um bit específico. A contagem com x &= x - 1 é eficiente porque cada iteração remove exatamente um bit 1, independentemente da posição.
Erros comuns
- Usar
flags |= ~maskpara desligar: isso ligaria todos os bits exceto o desejado. O correto éflags &= ~mask. - No
scanf, usar"%c%c"sem espaço antes do primeiro%c, o que pode consumir o newline anterior e bagunçar a leitura. Use" %c%c". - Esquecer de tratar
op == '0'e entrar em loop infinito se a entrada não terminar.
Outra forma de resolver
Pode-se usar uma tabela de máscaras e uma função separada para aplicar a operação, mas a solução acima já é clara e direta.
Saída esperada
flags = 0x5
bits ligados = 2