op1 | op2 | !op1 | op1 && op2 | op1 || op2 |
не 0 (1) | ||||
не 0 (1) | не 0 (1) | не 0 (1) | ||
не 0 (1) | не 0 (1) | |||
не 0 (1) | не 0 (1) | не 0 (1) | не 0 (1) |
Логические операции выполняются слева направо, причем для двуместных операций второй операнд может не вычисляться, если значение первого операнда однозначно определяет значение операции. Это происходит в том случае, если первый операнд для && равен 0 (результат операции тоже 0) и если первый операнд для || не 0 (результат операции тоже не 0).
Битовые операции
Любые данные, записанные в память ЭВМ, как известно, представляют собой последовательность бит, т.е. последовательность нулей и единиц. Например, любое число типа int будет занимать 2 байта в памяти, т.е 16 бит. Его можно рассматривать двояко: либо как целое число (так и делается при выполнении операций *,/, +, -, %), либо как последовательность бит, что возможно при использовании битовых операций.
Битовые операции выполняются независимо над каждым битом данных. Если операция двуместная, то она выполняется над соответствующими битами операндов.
|
|
В Си имеются следующие битовые операции:
~ битовое отрицание (одноместная),
& побитовое "и" (двуместная),
^ побитовое "исключающие или" (двуместная),
| побитовое "или" (двуместная).
Результат этих операций определяет таблица значений для всевозможных комбинаций бит двух операндов.
Результаты битовых операций
op1 | op2 | ~op1 | op1 & op2 | op1 ^ op2 | op1 | op2 |
Рассмотрим несколько примеров.
Первый пример показывает, как с помощью операции | можно установить в единицу выбранные биты операнда:
/* a = 00001001 = 9 */
char a, b; /* 00011010 = 26 */
a = 9; /* -------- */
b = a | 26 /* b = 31 */ /* b = 00011011 = 31 */
Следующий пример показывает, как с помощью операции & можно обнулить старшую часть байта:
char a, b; /* a = 00101101 = 45 */
a = 45; /* 00001111 */
b = a & 0x0F; /* -------- */
/* b = 00001101 = 13 */
К битовым операциям относятся операции сдвига << и >>:
a << b сдвиг битов переменной a влево на b позиций,
a >> b сдвиг битов переменной a вправо на b позиций.
Например:
char a, b;
a = 26; /* a = 00011010 = 26 */
b = a << 2; /* b = 01101000 = 104 */
Сдвиг влево равносилен умножению на 2 в соответствующей степени. Сдвиг вправо - делению на 2 в соответствующей степени.
Все битовые операции выполняются слева направо. В следующей строке приведены битовые операции в порядке уменьшения их приоритета.
~, << >>, &, ^, |
Для двуместных битовых операций определены дополнительные операции присваивания:
a <<= b; эквивалентно a = a << b,
a >>= b; эквивалентно a = a >> b,
|
|
a &= b; эквивалентно a = a & b,
a ^= b; эквивалентно a = a ^ b,
a |= b; эквивалентно a = a | b.
Приоритеты операций
Приоритет — очередность выполнения операций при вычислении выражения.
Приоритеты и направление рассмотренных выше операций сведены в следующую таблицу. Операции одинакового приоритета объединены в группы, чем выше положение группы в таблице, тем выше приоритет операций группы.
Таблица приоритетов операций
Операции одного приоритета | Направление выполнения операции. |
! ~ ++ -- (тип) sizeof | |
* / % | |
+ - | |
<< >> | |
< <= > >= | |
==!= | |
& | |
^ | |
| | |
&& | |
|| | |
= *= /= %= += -= <<= >>= &= ^= |= |
Операторы ветвления
Оператор ветвления применяется в случаях, когда выполнение или невыполнение некоторого набора команд должно зависеть от выполнения или невыполнения некоторого условия.