Ce face Operatori pe biți (& | ^ ~ << >>)
Operatorii pe biți compară bit cu bit două numere întregi. & păstrează biții care sunt 1 în ambele, | pe cei care sunt 1 în oricare, ^ pe cei diferiți, iar ~ inversează toți biții.
a << n mută biții lui a cu n poziții la stânga (înmulțire cu 2n), a >> n la dreapta (împărțire cu 2n pentru numere pozitive). Pentru deplasări, folosește tipuri fără semn: deplasarea unui număr negativ la stânga este comportament nedefinit.
Un caz tipic sunt steagurile: fiecare bit înseamnă o opțiune (citire, scriere, execuție). Setezi un bit cu |=, îl ștergi cu &= ~, îl verifici cu & și îl comuți cu ^=.
Exemple
Exemplul 1: Permisiuni ca steaguri
Fiecare permisiune are un bit propriu. 0x în %#x afișează valoarea în hexazecimal.
#include <stdio.h>
enum { CITIRE = 1u << 0, SCRIERE = 1u << 1, EXECUTIE = 1u << 2 };
int main(void) {
unsigned drepturi = CITIRE | SCRIERE;
printf("drepturi = %#x\n", drepturi);
printf("poate scrie: %s\n", (drepturi & SCRIERE) ? "da" : "nu");
printf("poate executa: %s\n", (drepturi & EXECUTIE) ? "da" : "nu");
drepturi &= ~SCRIERE; // șterge dreptul de scriere
drepturi |= EXECUTIE; // adaugă execuția
printf("după modificări = %#x\n", drepturi);
return 0;
}
Rezultat
drepturi = 0x3
poate scrie: da
poate executa: nu
după modificări = 0x5
Exemplul 2: Afișarea biților unui număr
Funcția testează fiecare bit, de la cel mai semnificativ, cu o mască 1u << i.
#include <stdio.h>
void biti(unsigned char x) {
for (int i = 7; i >= 0; i--) {
putchar((x & (1u << i)) ? '1' : '0');
}
putchar('\n');
}
int main(void) {
unsigned char a = 0x5A, b = 0x0F;
printf("a = "); biti(a);
printf("b = "); biti(b);
printf("a & b = "); biti(a & b);
printf("a | b = "); biti(a | b);
printf("a ^ b = "); biti(a ^ b);
printf("~a = "); biti((unsigned char)~a);
return 0;
}
Rezultat
a = 01011010
b = 00001111
a & b = 00001010
a | b = 01011111
a ^ b = 01010101
~a = 10100101
Exemplul 3: Deplasări: înmulțire și împărțire cu puteri ale lui 2
#include <stdio.h>
int main(void) {
unsigned x = 5;
printf("5 << 3 = %u\n", x << 3);
printf("40 >> 2 = %u\n", 40u >> 2);
unsigned culoare = 0xFF8800; // RGB
printf("roșu=%u verde=%u albastru=%u\n",
(culoare >> 16) & 0xFF, (culoare >> 8) & 0xFF, culoare & 0xFF);
return 0;
}
Rezultat
5 << 3 = 40
40 >> 2 = 10
roșu=255 verde=136 albastru=0
Greșeli frecvente
- Scrii
if (x & MASCA == MASCA).==are prioritate mai mare decât&; pune paranteze:if ((x & MASCA) == MASCA). - Deplasezi cu un număr de poziții mai mare sau egal cu lățimea tipului (
1u << 32pe ununsignedde 32 de biți). Este comportament nedefinit. - Folosești
^ca ridicare la putere. În C,2 ^ 3este 1 (SAU exclusiv); pentru putere foloseștepowsau înmulțiri.
Comenzi înrudite
Operatori de comparație și logici (== && || ! ?:): Compară valori și combină condiții: rezultatul este 1 (adevărat) sau 0 (fals); && și || se opresc cât mai devreme.stdint.h și limits.h: Tipuri întregi cu dimensiune exactă (int32_t, uint8_t) și constantele cu valorile minime și maxime ale tipurilor (INT_MAX).enum: Definește un set de constante întregi cu nume, de exemplu zilele săptămânii sau stările unei comenzi.Operatori aritmetici (+ - * / % ++ --): Adunare, scădere, înmulțire, împărțire, restul împărțirii, atribuiri compuse și incrementare cu ++ / –.