^= (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.