Алгоритмы C/C++

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

В этом уроке вы будете устанавливать, сбрасывать, инвертировать и проверять биты целого числа, чтобы хранить несколько состояний «вкл/выкл».

Введение

Каждый бит целого числа может хранить одно значение: истина или ложь. Поэтому в одном беззнаковом целом можно держать несколько независимых переключателей, которые называют флагами (flags). Этот приём битовых масок (bit mask) очень распространён в системном программировании и встраиваемых системах.

Главное

  • Проверяйте на пустом вводе, одном элементе, повторах и уже отсортированных данных.
  • Сначала добейтесь правильной работы кода, а потом оптимизируйте.
  • В реальном коде отдавайте предпочтение готовым функциям стандартной библиотеки.

Примеры кода на C и C++

C
Запустить →
main.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
C++
Запустить →
main.cpp
#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() и выводит значение в двоичном виде.

C

Циклы, указатели, длины и временные буферы пишутся явно.

C++

Итераторы и стандартные алгоритмы отделяют обработку от способа хранения данных.

Упражнения для практики

Запустите обе версии, а затем измените код, чтобы увидеть разницу в безопасности, которую даёт каждый язык.

  • Пройдите каждое сравнение на бумаге.
  • Проверьте на повторах и на очень больших и очень маленьких значениях.
  • Измерьте время работы своего кода и сравните его со стандартной библиотекой.

Попрактикуйтесь на задаче

Примените материал этого урока к реальной задаче. Каждая задача запускается в браузере, с мгновенными тестами и разбором от ИИ.

Все задачи