|= (compound bitwise OR)
Оператор |= устанавливает нужные биты переменной в 1, не затрагивая остальные — удобен для работы с регистрами и флагами состояния. |=
Полная статья
Описание
Оператор |= — это сокращённая форма побитового OR, которая применяется к самой переменной и сохраняет результат обратно в неё. Главная практическая задача этого оператора — установить отдельные биты в 1, не трогая остальные биты переменной.
Чтобы понять, как это работает, вспомним таблицу побитового OR |:
0 0 1 1 operand1
0 1 0 1 operand2
----------
0 1 1 1 (operand1 | operand2) - returned result
Ключевое свойство: бит OR с 0 остаётся прежним, бит OR с 1 всегда становится 1. Именно это позволяет использовать |= как точечный инструмент для включения нужных битов.
Синтаксис
x |= y; // equivalent to x = x | y;
Параметры
x— переменная, биты которой нужно изменить. Допустимые типы:char,int,long.y— переменная или константа-маска, задающая, какие биты установить в 1. Допустимые типы:char,int,long.
Пример кода
Если myByte — байтовая переменная, то биты, для которых в маске стоит 0, не изменятся:
myByte | 0b00000000 = myByte;
А биты, для которых в маске стоит 1, будут принудительно установлены в 1:
myByte | 0b11111111 = 0b11111111;
Примечания и предупреждения
Для работы с отдельными битами удобнее всего записывать маски в двоичном виде с префиксом 0b — так сразу видно, какие именно биты будут затронуты. Числа при этом не меняют своего значения, просто двоичная запись делает намерение очевидным.
Чтобы установить биты 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 1 1
bits unchanged
bits set
То же самое, но с символом 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 1 1
bits unchanged
bits set
Полный пример с конкретными значениями:
myByte = 0b10101010;
myByte |= 0b00000011 == 0b10101011;
Где применяется
- Управление портами и регистрами: включить отдельный пин или периферийный модуль, не сбрасывая соседние флаги.
- Протоколы и флаги состояния: выставить бит «данные готовы» или «ошибка» в байте статуса.
- Работа с RGB-светодиодами или дисплеями: включить отдельный канал цвета, не затрагивая остальные.
- Конфигурация аппаратных регистров: установить нужные биты конфигурации таймера или UART через регистры AVR.
Практические замечания
|=только устанавливает биты в 1 — сбросить бит в 0 с его помощью нельзя. Для сброса используйте&=с инвертированной маской.- Маску удобно строить через сдвиг:
1 << 3установит бит 3,(1 << 3) | (1 << 5)— биты 3 и 5 одновременно. - Если нужно проверить, установлен ли бит, используйте обычный
&, а не|=. - Операция не блокирующая и выполняется мгновенно — никаких задержек она не вносит.
- При работе с 8-битными переменными типа
charследите за знаковостью: если нужен беззнаковый байт, объявляйте переменную какbyteилиuint8_t, чтобы избежать неожиданного поведения при сдвигах.