C/C++ Работа с битами

В Си существуют 6 операторов для манипулирования битами:

<<  — сдвиг влево
>>  — сдвиг вправо
~   —  поразрядная инверсия
|    — поразрядное ИЛИ
&  — поразрядное И
^   —  поразрядное исключающее ИЛИ

Если нужно записать сразу несколько бит:

unsigned char x = 0;
x = 1<<номер_бита | 1<<номер_бита | 1<<номер_бита .... ;

Номера битов отсчитываются справа налево, начиная с нуля. 0 — это младший бит (справа), 7 — это старший  бит (слева).

Если нужно записывать определенные биты, не стирая другие:

Чтобы записать единицу в бит n:

x |= (1 << n);

Чтобы записать ноль в бит n:

x &= ~(1 << n);

Если нужно инвертировать состояние бита:

x ^= (1 << n);

Если нужно прочитать отдельный бит:

unsigned char x = (1 << 2) | (1 << 3) | (1 << 7);
if (x & (1 << 2)) {  /* во второй бит вписана единица */ }
if (x & (1 << 3)) {  /* в третий бит вписана единица */ }
if (x & (1 << 7)) {  /* в седьмой бит вписана единица */ }

Если нужно определить, что в X на N-й позиции:

bool b = (bool((1 << n)  &  x))

Если нужно обнулить один или несколько битов:

Для обнуления отдельных битов используется оператор &

Пример:

int x = 58;       // 00111010
int y = x & 0x0F; // 00001010

Обнулить несколько битов можно и так:

x = x & (~((1<<3)|(1<<5)|(1<<6))); //обнуляем третий, пятый и шестой биты

Если нужно установить заданные биты в единицу. Используют оператор |

int x = 155
x = x | 4;     //устанавливаем в единицу второй бит переменной x
    155     0b10011011
 |
      4     0b00000100
    159     0b10011111

Сдвиг влево <<

Сдвигает число на n разрядов влево

unsigned char x = 3;  //0b00000011
x = x << 3;           //0b00011000 (24)

Сдвиг вправо >>

Сдвигает число на n разрядов вправо

unsigned char x = 255;  //0b11111111
x = x >> 3;             //0b00011111 (31)

C/C++ Работа с битами: 4 комментария

  1. Это одна из типичных задач на работу с битами, которые любят давать на собеседовании.

  2. Я ни разу не программист, поэтому для меня это было сущим адом, но именно ваша статья помогла мне разобраться. Спасибо!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *