Побитовые логические операции. Операции над битамиВ СИ предусмотрен набор операций для работы с отдельными битами слов. Эти операции нельзя применять к переменным вещественного типа (float, double). Перечень операций над битами и их обозначения: ~ - дополнение (унарная операция); инвертирование (одноместная операция); & - побитовое И - конъюнкция; | - побитовое включающее ИЛИ - дизъюнкция; ^ - побитовое исключающее ИЛИ - сложение по модулю 2; >> - сдвиг вправо; << - сдвиг влево. Пары символов (>>,<<) разделять нельзя. Общий вид операции инвертирования: ~ <выражение> Остальные операции над битами имеют вид: <выражение1> <знак_операции> <выражение2> Операндами операций над битами могут быть только выражения, приводимые к целому типу. Операции (~, &, |, ^) выполняются поразрядно над всеми битами операндов (знаковый разряд особо не выделяется): ~0xF0 Û x0F 0xFF & 0x0F Û x0F 0xF0 | 0x11 Û xF1 0xF4 ^ 0xF5 Û x01 Операция & часто используется для маскирования некоторого множества битов. Например, оператор w = n & 0177 передает в w семь младших битов n, полагая остальные равными нулю. Операции сдвига выполняются также для всех разрядов с потерей выходящих за границы битов. Операция (!) используется для включения битов w = x! y, устанавливает в единицу те биты в x, которые =1 в y. Необходимо отличать побитовые операции & и! от логических операций && и ||, которые подразумевают вычисление значения истинности слева направо. Если x=1, y=2, то x & y равно нулю, а x && y равно 1. 0x81<<1 Û 0x02 0x81>>1 Û 0x40 Если выражение1 имеет тип unsigned, то при сдвиге вправо освобождающиеся разряды гарантированно заполняются нулями (логический сдвиг). Выражения типа signed могут, но не обязательно, сдвигаться вправо с копированием знакового разряда (арифметический сдвиг). При сдвиге влево освобождающиеся разряды всегда заполняются нулями. Если выражение2 отрицательно либо больше длины выражения1 в битах, то результат операции сдвига не. Унарная операция (~) дает дополнение к целому. Это означает, что каждый бит со значением 1 получает значение 0 и наоборот. Эта операция обычно оказывается полезной в выражениях типа: X & (~)077, где последние 6 битов X маскируются нулем. Это выражение не зависит от длины слова и поэтому предпочтительнее, чем, например: X & 0177700, где предполагается, что X занимает 16 битов, такая переносимая форма не требует никаких дополнительных затрат. Операции сдвига << и >> осуществляют соответственно сдвиг вправо (влево) своего левого операнда, на число битовых позиций, задаваемых правым операндом. Таким образом, x<<2 сдвигает x влево на две позиции, заполняя, освобождающиеся биты, нулями, что эквивалентно умножению на 4. Операции сдвига вправо на k разрядов весьма эффективны для деления, а сдвиг влево - для умножения целых чисел на 2 в степени k: x<<1 «x*2 x>>1 «x/2 x<<3 «x*8 Подобное применение операций сдвига безопасно для беззнаковых и положительных значений выражения1. Двуместные операции над битами (&, |, ^, <<, >>) могут использоваться в сокращенных формах записи операции присваивания: int i,j,k; ... i |= j «i = i | j - включение в поле i единиц из поля j; i &= 0xFF «i = i & 0xFF - выделение в поле i единиц по маске поля 0x00FF; k ^= j - выделение в поле k отличающихся разрядов в полях k и j; i ^= i - обнуление всех разрядов поля i.
Операции над битами реализуются, как правило, одной машинной командой и рекомендуются для использования во всех подходящих случаях. В математическом смысле операнды логических операций над битами можно рассматривать как отображение некоторых множеств с размерностью не более разрядности операнда на значения {0,1}. Пусть единица означает обладание элемента множества некоторым свойством, тогда очевидна теоретико-множественная интерпретация рассматриваемых операций: ~ - дополнение; | - объединение; & - пересечение. Простейшее применение - проверка нечетности целого числа: int i; ... if (i &1) printf(" Значение i четно!");
Комбинирование операций над битами с арифметическими операциями часто позволяет упростить выражения. Например, получение размера области в параграфах размером 16 байт для размещения объекта размером x байт: (x + 15)>>4 Другие возможности оперирования над битами: - использование структур с битовыми полями; - доступ к битам как разрядам арифметических данных.
6.10. Операция, (запятая) Данная операция используется при организации строго гарантированной последовательности вычисления выражений. Форма записи: выражение1, …, выражениеN; выражения1,…,N вычисляются гарантированно последовательно и результатом операции становится значение выражения N. Пример: m=(i=1, j=i++, k=6, n=i+j+k); получим последовательность вычислений: i=1, j=i=1, i=2, k=6, n=2+1+6, и в результате m=n=9. Данный пример ничем не отличается от такого участка кода: i =1; j = i; i++; k = 6; n = i+j+k; m = n; Данная операция используется там, где по синтаксису допустима только одна операция, а нам необходимо разместить несколько последовательно выполняемых операций (см. оператор for). При передаче последовательности вычислений в функцию в качестве параметра – их необходимо взять в скобки.
|