Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Название:Язык программирования C. Лекции и упражнения (6-е изд.) 2015
- Автор:
- Жанр:
- Издательство:Вильямс
- Год:0101
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Стивен Прата - Язык программирования C. Лекции и упражнения (6-е изд.) 2015 краткое содержание
Язык программирования C. Лекции и упражнения (6-е изд.) 2015 - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
(10010011) & (00111101) // выражение
получается следующее значение:
(00010001) // результат
Причина в том, что только нулевой и четвертый биты равны 1 в обоих операндах. В С также имеется операция “И”, объединенная с присваиванием: &=.
Оператор
val &= 0377;
дает такой же результат, как и следующий оператор:
val = val & 0377;
Побитовая операция “ИЛИ": |
Двоичная операция | создает новое значение за счет выполнения побитового сравнения двух операндов. Для каждой позиции бит будет равен 1, если любой из соответствующих битов в операндах равен 1. (В терминах истинный/ложный можно сказать, что результат будет истинным в случае, когда один или другой битовый операнд является истинным либо сразу оба.)
634 глава 15
Таким образом, в результате вычисления выражения
(10010011) | (00111101) // выражение
получается следующее значение:
(10111111) // результат
Причина в том, что биты во всех позициях кроме 6 имеют значение 1 в одном или в другом операнде (или в обоих). В С также существует операция “ИЛИ”, объединенная с присваиванием: |=. Оператор
val |= 0377;
дает тот же результат, что и следующий оператор:
val = val | 0377;
Побитовое "исключающее ИЛИ": *
Двоичная операция ^выполняет побитовое сравнение двух операндов. Для каждой позиции результирующий бит будет равен 1, если один или другой (но не оба) из соответствующих битов в операндах равен 1. (В терминах истинный/ложный можно сказать, что результат будет истинным в случае, когда один или другой битовый операнд является истинным, но не оба.) Таким образом, в результате вычисления выражения
(10010011) ^ (00111101) // выражение
получается следующее значение:
(10101110) // результат
Обратите внимание, что поскольку бит 0 равен 1 у обоих операндов, результирующий бит 0 получает значение 0.
В языке С также имеется операция “исключающее ИЛИ”, объединенная с присваиванием: ^=. Оператор
val ^= 0377;
дает тот же результат, что и следующий оператор:
val = val ^0377;
Случай применения: маски
Побитовая операция “И” часто используется с маской. Маска — это комбинация битов, в которой некоторые биты включены (1), а некоторые выключены (0). Чтобы понять, почему ее так назвали, давайте посмотрим, что происходит, когда мы объединяем какую-то величину с маской с применением операции &. Для примера предположим, что вы определили символическую константу MASK как 2 (т.е. 00000010), у которой ненулевым является только бит с номером 1. Тогда оператор
flags = flags & MASK;
приведет к установке всех битов flags (кроме первого) в 0, т.к. любой бит, объединяемый с 0 посредством операции “И”, дает 0. Бит номер 1 переменной остается неизменным. (Если бит равен 1, то значением 1 & 1 будет 1; если же бит равен 0, то 0 & 1 дает 0.) Такой процесс называется “использованием маски”, поскольку нули в маске скрывают соответствующие биты в переменной flags.
Развивая аналогию, биты с 0 в маске можно считать непрозрачными, а биты с 1 - прозрачными. Выражение flags & MASK похоже на накрывание маской комбинации битов flags; видимыми из-под маски будут только те биты, которым в MASK соответствуют биты с 1 (рис. 15.2).
Манипулирование битами 635
Рис. 15.2. Наглядное представление маски
Для сокращения кода можно применить операцию “И”, объединенную с присваиванием:
flags &= MASK;
Ниже показан один распространенный случай использования этой операции:
ch &= 0xff; /* или ch &= 0377; */
Вспомните, что значение 0xff записывается как 11111111 в двоичном или как 0377 в восьмеричном виде. Эта маска оставляет последние восемь битов в ch без изменений, а остальные устанавливает в 0. Независимо от того, сколько битов содержит исходная переменная ch — 8, 16 или более, — финальное значение усекается до величины, которая умещается в один 8-битовый байт. В данном случае маска имеет ширину 8 битов.
Случай применения: включение (установка) битов
Иногда требуется включить отдельные биты в значении, оставив остальные без изменений. Например, компьютер IBM PC управляет оборудованием, отправляя нужные значения в порты. Для активизации, скажем, динамика, необходимо включить бит 1, а остальные биты оставить неизменными. Этого можно сделать с помощью побитовой операции “ИЛИ”.
Например, пусть имеется константа MASK, в которой бит 1 установлен в 1. Тогда оператор
flags = flags | MASK;
включает бит номер 1 в переменной flags и оставляет все остальные биты без изменений. Это объясняется тем, что любой бит, объединенный с 0 посредством операции , остается самим собой, а объединенный с 1 с использованием I, становится равным 1.
Например, пусть flags равно 00001111 и MASK — 10110110. Выражение
flags | MASK становится
(00001111) | (10110110) // выражение
и после вычисления дает следующий результат:
(10111111) // результат
636 Глава 15
Все биты, установленные в 1 внутри MASK, также будут установлены в 1 в результате. Все биты в flags, которые соответствуют битам 0 в MASK, остаются неизмененными.
Для краткости можно использовать побитовую операцию “ИЛИ”, объединенную с присваиванием:
flags |= MASK;
Этот оператор установит в 1 те биты falgs, которым соответствуют включенные биты в MASK, оставив другие биты без изменений.
Случай применения: выключение (очистка) битов
Точно так же, как удобно иметь возможность включать отдельные биты, не затрагивая остальные, не менее удобно располагать возможностью их выключения. Предположим, что требуется отключить бит номер 1 в переменной flags. И снова MASK имеет включенный только бит 1. Можно воспользоваться следующим оператором:
flags = flags & ~MASK;
Поскольку в MASK все биты кроме бита 1 выключены, выражение -MASK дает значение, в котором все биты кроме бита 1 включены. Объединение 1 с любым битом, используя операцию &, дает сам этот бит, поэтому оператор оставляет все биты кроме бита 1 без изменений. Объединение 0 с любым битом посредством операции & дает О независимо от исходного значения бита.
Например, пусть flags равно 00001111 и MASK — 10110110. Выражение
flags & ~MASK становится
(00001111) & ^(10110110) // выражение
и после вычисления дает следующий результат:
(00001001) // результат
Все биты, установленные в 1 внутри MASK, будут установлены в 0 в результате. Все биты в flags, которые соответствуют битам 0 в MASK, остаются неизмененными.
Ниже представлена сокращенная форма:
flags &= -MASK;
Случай применения: переключение битов
Переключение бита означает его выключение, если он включен, и включение, если выключен. Для переключения битов можно применять побитовую операцию исключающего “ИЛИ”. Идея в том, что если b — это установленное состояние бита (1 или 0), то 1 ^b равно 0, когда b равно 1, и 1, когда b равно 0. Кроме того, выражение 0 ^b дает b независимо от значения b. Следовательно, в результате объединения значения с маской с использованием операции ^биты, соответствующие 1 в маске, переключаются, а биты, соответствующие 0 в маске, останутся неизмененными. Чтобы переключить бит 1 переменной flags, можно выполнить одно из следующих действий:
Читать дальшеИнтервал:
Закладка: