Les opérateurs bit à bit contrôlent les bits individuels des types numériques entiers :
& — ET bit à bit| — OU bit à bit^ — OU exclusif bit à bit~ — NON bit à bit<< — décalage à gauche>> — décalage à droiteParticularités :
int, unsigned int, etc.).signed) lors des décalages à droite (>>) peuvent produire un décalage arithmétique ou logique — cela dépend du compilateur.unsigned pour éviter l'extension du signe.Exemple :
unsigned int flags = 0; flags |= 0x1; // Mettre à 1 le 0ème bit flags &= ~0x2; // Réinitialiser le 1er bit if ((flags & 0x4) != 0) { /* ... */ } // Vérifier le 2ème bit
Quelle est la différence entre le décalage à droite (
>>) pour les typessigned intetunsigned int?
Réponse souvent erronée : On pense que le décalage à droite insère toujours des zéros à gauche, peu importe le signe.
Réponse correcte :
Pour le type unsigned int, le décalage à droite (>>) insère toujours des zéros. Pour le signed int, soit le signe est inséré (des uns si le nombre est négatif), soit des zéros — cela dépend de l'implémentation du compilateur (architecture et règles de la norme C).
Exemple :
signed int a = -8; unsigned int b = (unsigned int)a; printf("%d ", a >> 1); printf("%u ", b >> 1);
Dans le premier cas, le résultat dépend du compilateur ; dans le second, il s'agit toujours d'un décalage logique avec des zéros.
Histoire
Dans le code de traitement du protocole, les drapeaux de signalisation étaient stockés dans un type char. Le programmeur a appliqué un décalage de 8 bits (flag << 8), ce qui a conduit à une perte de toutes les données en raison d'un débordement et des règles de promotion des types — le résultat était toujours égal à zéro.
Histoire
Lecture des données depuis un protocole réseau (big-endian). L'utilisation d'opérations bit à bit pour combiner des octets n'a pas été accompagnée d'une conversion en unsigned, ce qui a parfois conduit à des valeurs négatives inattendues lors de la lecture d'un champ de structure.
Histoire
Utilisation de ~ (NON bit à bit) pour réinitialiser des bits dans une valeur de type int (par exemple, ~0x80) était interprétée comme 0x7F, mais cela se révélait en réalité un nombre négatif -129, ce qui entraînait des erreurs lors de calculs ultérieurs et de vérifications logiques.