Главная chevron_right Структура chevron_right Составные операторы chevron_right ^= (compound bitwise XOR)

^= (compound bitwise XOR)

Оператор ^= применяет побитовое XOR к переменной и сохраняет результат в ней же — удобно переключать отдельные биты, не трогая остальные.

Полная статья

Описание

Составной побитовый оператор XOR ^= — это сокращённая запись, которая применяет побитовое исключающее ИЛИ к переменной и тут же сохраняет результат в ней же. Главная практическая ценность оператора — переключение (инвертирование) конкретных битов переменной без изменения остальных.

Краткое напоминание о том, как работает побитовый XOR ^:

0  0  1  1    operand1
0  1  0  1    operand2
----------
0  1  1  0    (operand1 ^ operand2) - returned result

Правило простое: бит результата равен 1, если соответствующие биты операндов различаются, и 0, если они совпадают.

Синтаксис

x ^= y; // equivalent to x = x ^ y;

Параметры

  • x: переменная, над которой выполняется операция. Допустимые типы данных: char, int, long.
  • y: переменная или константа, задающая маску. Допустимые типы данных: char, int, long.

Пример кода

Здесь хорошо видна логика маскирования. Если myByte — байтовая переменная, то биты, для которых в маске стоит 0, не изменятся:

myByte ^ 0b00000000 = myByte;

А биты, для которых в маске стоит 1, переключатся на противоположное значение:

myByte ^ 0b11111111 = ~myByte;

Примечания и предупреждения

При работе с побитовыми операторами удобно записывать маски в двоичном виде с префиксом 0b — так сразу видно, какие именно биты затрагиваются. Числа в других форматах имеют то же значение, но читать их сложнее. В примерах ниже 0b00000000 показан явно, хотя ноль есть ноль в любом представлении.

Чтобы переключить только биты 0 и 1 переменной, оставив остальные нетронутыми, используйте маску 0b00000011:

1  0  1  0  1  0  1  0    variable
0  0  0  0  0  0  1  1    mask
----------------------
1  0  1  0  1  0  0  1

bits unchanged
                 bits toggled

То же самое в символическом виде, где x — значение бита переменной, а ~x — его дополнение:

x  x  x  x  x  x  x  x    variable
0  0  0  0  0  0  1  1    mask
----------------------
x  x  x  x  x  x ~x ~x

bits unchanged
                 bits set

Итого, если:

myByte = 0b10101010;
myByte ^= 0b00000011 == 0b10101001;

Где применяется

  • Управление светодиодами или реле по битовому флагу — переключение состояния одним оператором без чтения текущего значения вручную.
  • Простая инверсия флагов в байте состояния — например, переключение режима работы устройства.
  • Генерация чередующихся сигналов — если в цикле применять ^= с маской, бит будет менять значение на каждой итерации.
  • Аппаратные регистры — при прямой работе с портами микроконтроллера для инвертирования отдельных линий.

Практические замечания

  • Оператор ^= изменяет переменную на месте: отдельно читать и записывать её не нужно.
  • Маска определяет, какие биты будут переключены. Биты с 0 в маске остаются нетронутыми, биты с 1 инвертируются.
  • Используйте двоичный формат 0b... для масок — это делает намерение очевидным при чтении кода.
  • Оператор работает с типами char, int и long; для byte используйте явное приведение или тип int.
  • Не путайте ^= с оператором возведения в степень — в C++ и Arduino такого оператора нет, ^ всегда означает XOR.

Полезные материалы