Работа с битами в C и C++
В этом уроке вы будете устанавливать, сбрасывать, инвертировать и проверять биты целого числа, чтобы хранить несколько состояний «вкл/выкл».
Введение
Каждый бит целого числа может хранить одно значение: истина или ложь. Поэтому в одном беззнаковом целом можно держать несколько независимых переключателей, которые называют флагами (flags). Этот приём битовых масок (bit mask) очень распространён в системном программировании и встраиваемых системах.
Главное
- Проверяйте на пустом вводе, одном элементе, повторах и уже отсортированных данных.
- Сначала добейтесь правильной работы кода, а потом оптимизируйте.
- В реальном коде отдавайте предпочтение готовым функциям стандартной библиотеки.
Примеры кода на C и C++
#include <stdio.h>
int main(void) {
unsigned flags = 0;
flags |= 1u << 1;
flags |= 1u << 3;
flags ^= 1u << 1;
printf("flags=%u bit3=%u\n", flags, (flags >> 3) & 1u);
}
flags=8 bit3=1
#include <bitset>
#include <iostream>
int main() {
std::bitset<4> flags;
flags.set(1);
flags.set(3);
flags.flip(1);
std::cout << "flags=" << flags
<< " bit3=" << flags.test(3) << '\n';
}
flags=1000 bit3=1
Сравнение C и C++
Выражение 1u << n создаёт число, в котором единица стоит только в бите n. Оператор |= устанавливает бит, ^= инвертирует его, а (flags >> 3) & 1u проверяет бит 3. После установки битов 1 и 3 и повторной инверсии бита 1 установленным остаётся только бит 3, поэтому flags равно 8. Используйте беззнаковые типы (unsigned), чтобы сдвиги давали предсказуемый результат. В C++ std::bitset предлагает понятные методы вроде set() и flip() и выводит значение в двоичном виде.
Циклы, указатели, длины и временные буферы пишутся явно.
Итераторы и стандартные алгоритмы отделяют обработку от способа хранения данных.
Упражнения для практики
Запустите обе версии, а затем измените код, чтобы увидеть разницу в безопасности, которую даёт каждый язык.
- Пройдите каждое сравнение на бумаге.
- Проверьте на повторах и на очень больших и очень маленьких значениях.
- Измерьте время работы своего кода и сравните его со стандартной библиотекой.
Попрактикуйтесь на задаче
Примените материал этого урока к реальной задаче. Каждая задача запускается в браузере, с мгновенными тестами и разбором от ИИ.
- Степень двойки Проверьте, является ли число степенью двойки. Легко
- Минимальное количество поездок на лифте Разбейте людей на минимальное количество поездок на лифте с ограничением по весу. Сложно