cpp

Побитовые операторы

Побитовые операторы предназначены для манипуляции отдельными битами. Эти операторы нельзя применять к вещественным числам, логическим значениям и другим более сложным типам. Язык C++ поддерживает следующие побитовые операторы:

  • ~ — двоичная инверсия. Значение каждого бита заменяется на противоположное:
unsigned char x = 100;          // 01100100
x = (unsigned char) ~x;         // 10011011
// #include <cstdlib>
char str[100] = {0};
_itoa_s(x, str, 100, 2);
std::cout << str << std::endl;  // 10011011
  • & — двоичное И:
unsigned char x = 100;          // 01100100
unsigned char y = 75;           // 01001011
unsigned char z = x & y;        // 01000000
  • | — двоичное ИЛИ:
unsigned char x = 100;          // 01100100
unsigned char y = 75;           // 01001011
unsigned char z = x | y;        // 01101111
  • ^ — двоичное исключающее ИЛИ:
unsigned char x = 100;          // 01100100
unsigned char y = 250;          // 11111010
unsigned char z = x ^ y;        // 10011110
  • << — сдвиг влево — сдвигает двоичное представление числа влево на один или более разрядов и заполняет разряды справа нулями:
unsigned char x = 100;          // 01100100
x = (unsigned char)(x << 1);    // 11001000
x = (unsigned char)(x << 1);    // 10010000
x = (unsigned char)(x << 2);    // 01000000
Примечание
  • >> — сдвиг вправо — сдвигает двоичное представление числа вправо на один или более разрядов и заполняет разряды слева нулями, если число положительное:
unsigned char x = 100;          // 01100100
x = (unsigned char)(x >> 1);    // 00110010
x = (unsigned char)(x >> 1);    // 00011001
x = (unsigned char)(x >> 2);    // 00000110

Если число отрицательное, то разряды слева заполняются единицами:

char x = -127;                  // 10000001
x = (char)(x >> 1);             // 11000000
x = (char)(x >> 2);             // 11110000
x = (char)(x << 1);             // 11100000
x = (char)(x >> 1);             // 11110000
Примечание

Наиболее часто двоичное представление числа используется для хранения различных флагов (0 — флаг сброшен, 1 — флаг установлен). Примеры установки, снятия и проверки установки флага приведены в листинге 4.2. Чтобы иметь возможность видеть результат в окне консоли, дополнительно напишем функцию, позволяющую преобразовать число типа unsigned char в строку в двоичном формате.

Листинг 4.2. Работа с флагами

#include <iostream>
#include <clocale>

char *ucharToBinaryString(unsigned char x, char *str);

int main() {
   std::setlocale(LC_ALL, "Russian_Russia.1251");
   char str[9] = "";
   const unsigned char FLAG1 = 1,  FLAG2 = 2,  FLAG3 = 4, FLAG4 = 8,
                       FLAG5 = 16, FLAG6 = 32, FLAG7 = 64, FLAG8 = 128;
   unsigned char x = 0;    // Все флаги сброшены
   std::cout << ucharToBinaryString(x, str) << std::endl; // 00000000
   unsigned char y = 0xFF; // Все флаги установлены
   std::cout << ucharToBinaryString(y, str) << std::endl; // 11111111
   // Устанавливаем флаги FLAG1 и FLAG7
   x = x | FLAG1 | FLAG7;
   std::cout << ucharToBinaryString(x, str) << std::endl; // 01000001
   // Устанавливаем флаги FLAG4 и FLAG5
   x = x | FLAG4 | FLAG5;
   std::cout << ucharToBinaryString(x, str) << std::endl; // 01011001
   // Снимаем флаги FLAG4 и FLAG5
   x = x ^ FLAG4 ^ FLAG5;
   std::cout << ucharToBinaryString(x, str) << std::endl; // 01000001
   // Проверка установки флага FLAG1
   if ((x & FLAG1) != 0) {
      std::cout << "FLAG1 установлен" << std::endl;
   }
   std::cout << ucharToBinaryString(FLAG1, str) << '\n';  // 00000001
   std::cout << ucharToBinaryString(FLAG2, str) << '\n';  // 00000010
   std::cout << ucharToBinaryString(FLAG3, str) << '\n';  // 00000100
   std::cout << ucharToBinaryString(FLAG4, str) << '\n';  // 00001000
   std::cout << ucharToBinaryString(FLAG5, str) << '\n';  // 00010000
   std::cout << ucharToBinaryString(FLAG6, str) << '\n';  // 00100000
   std::cout << ucharToBinaryString(FLAG7, str) << '\n';  // 01000000
   std::cout << ucharToBinaryString(FLAG8, str) << '\n';  // 10000000
   return 0;
}

char *ucharToBinaryString(unsigned char x, char *str) {
   int k = 7;
   while (k >= 0) {
      if ((x & 1) != 0) {          // Проверка статуса последнего бита
         str[k] = '1';
      }
      else {
         str[k] = '0';
      }
      x = (unsigned char)(x >> 1); // Сдвиг на один разряд вправо
      --k;
   }
   str[8] = '\0';
   return str;
}

Учебник C++ (Qt Creator и MinGW)
Учебник C++ (Qt Creator и MinGW) в формате PDF