Поразрядные операторы И, ИЛИ, исключающее ИЛИ и НЕ



 

Поразрядные операторы И , ИЛИ , исключающее ИЛИ и НЕ (обозначаемые символами & , | , ^ и ~ соответственно) выполняют те же операции, что и их логические эквиваленты (т.е. они действуют согласно той же таблице истинности). Различие состоит лишь в том, что поразрядные операции работают на побитовой основе. В следующей таблице показан результат выполнения каждой поразрядной операции для всех возможных сочетаний операндов (нулей и единиц).

 

 

Как видно из таблицы, результат применения оператора XOR (исключающее ИЛИ) будет равен значению ИСТИНА (1) только в том случае, если истинен (равен значению 1) лишь один из операндов; в противном случае результат принимает значение ЛОЖЬ (0).

Поразрядный оператор И можно представить как способ подавления битовой информации. Это значит, что 0 в любом операнде, обеспечит установку в 0 соответствующего бита результата. Вот пример.

1101 0011

& 1010 1010

1000 0010

Следующая программа считывает символы с клавиатуры и преобразует любой строчный символ в его прописной эквивалент путем установки шестого бита равным значению 0 . Набор символов ASCII определен так, что строчные буквы имеют почти такой же код, что и прописные, за исключением того, что код первых отличается от кода вторых ровно на 32 [только для латинского алфавита]. Следовательно, как показано в этой программе, чтобы из строчной буквы сделать прописную, достаточно обнулить ее шестой бит.

 

 

Значение 223 , используемое в инструкции поразрядного И , является десятичным представлением двоичного числа 1101 1111 . Следовательно, эта операция И оставляет все биты в переменной ch нетронутыми, за исключением шестого (он сбрасывается в нуль).

Оператор И также полезно использовать, если нужно определить, установлен ли интересующий вас бит (т.е. равен ли он значению 1 ) или нет. Например, при выполнении следующей инструкции вы узнаете, установлен ли 4‑й бит в переменной status ,

 

 

Чтобы понять, почему для тестирования четвертого бита используется число 8 , вспомните, что в двоичной системе счисления число 8 представляется как 0000 1000 , т.е. в числе 8 установлен только четвертый разряд. Поэтому условное выражение инструкции if даст значение ИСТИНА только в том случае, если четвертый бит переменной status также установлен (равен 1). Интересное использование этого метода показано на примере функции disp_binary() . Она отображает в двоичном формате конфигурацию битов своего аргумента. Мы будем использовать функцию disp_binary() ниже в этой главе для исследования возможностей других поразрядных операций.

 

 

Функция disp_binary() , используя поразрядный оператор И , последовательно тестирует каждый бит младшего байта переменной u , чтобы определить, установлен он или сброшен. Если он установлен, отображается цифра 1 , в противном случае – цифра 0 . Интереса ради попробуйте расширить эту функцию так, чтобы она отображала все биты переменной u , а не только ее младший байт.

Поразрядный оператор ИЛИ , в противоположность поразрядному И , удобно использовать для установки нужных битов в единицу. При выполнении операции ИЛИ наличие в любом операнде бита, равного 1 , означает, что в результате соответствующий бит также будет равен единице. Вот пример.

1101 0011

| 1010 1010

1111 1011

Можно использовать оператор ИЛИ для превращения рассмотренной выше программы (которая преобразует строчные символы в их прописные эквиваленты) в ее "противоположность", т.е. теперь, как показано ниже, она будет преобразовывать прописные буквы в строчные.

 

 

Установка шестого бита превращает прописную букву в ее строчный эквивалент. Поразрядное исключающее ИЛИ (XOR) устанавливает в единицу бит результата только в том случае, если соответствующие биты операндов отличаются один от другого, т.е. не равны. Вот пример:

0111 1111

^ 1011 1001

1100 0110

Унарный оператор НЕ (или оператор дополнения до 1) инвертирует состояние всех битов своего операнда. Например, если целочисленное значение (хранимое в переменной А ), представляет собой двоичный код 1001 0110 , то в результате операции получим двоичный код 0110 1001 .

В следующей программе демонстрируется использование оператора НЕ посредством отображения некоторого числа и его дополнения до 1 в двоичном коде с помощью приведенной выше функции disp_binary() .

 

 

Вот как выглядят результаты выполнения этой программы.

 

 

И еще. Не путайте логические и поразрядные операторы. Они выполняют различные действия. Операторы & , | и ~ применяются непосредственно к каждому биту значения в отдельности. Эквивалентные логические операторы обрабатывают в качестве операндов значения ИСТИНА/ЛОЖЬ (не нуль/нуль). Поэтому поразрядные операторы нельзя использовать вместо их логических эквивалентов в условных выражениях. Например, если значение х равно 7 , то выражение х && 8 имеет значение ИСТИНА, в то время как выражение х & 8 дает значение ЛОЖЬ.

Узелок на память. Оператор отношения или логический оператор всегда генерирует результат, который имеет значение ИСТИНА или ЛОЖЬ, в то время как аналогичный поразрядный оператор генерирует значение, получаемое согласно таблице истинности конкретной операции.

 

Операторы сдвига

 

Операторы сдвига, ">>" и "<<" сдвигают все биты в значении вправо или влево.

Общий формат использования оператора сдвига вправо выглядит так.

 

 

А оператор сдвига влево используется так.

 

 

Операторы сдвига предназначены для сдвига битов в рамках целочисленного значения.

Здесь элемент число_битов указывает, на сколько позиций должно быть сдвинуто значение . При каждом сдвиге влево все биты, составляющее значение, сдвигаются влево на одну позицию, а в младший разряд записывается нуль. При каждом сдвиге вправо все биты сдвигаются, соответственно, вправо. Если сдвигу вправо подвергается значение без знака, в старший разряд записывается нуль. Если же сдвигу вправо подвергается значение со знаком, значение знакового разряда сохраняется. Как вы помните, отрицательные целые числа представляются установкой старшего разряда числа равным единице. Таким образом, если сдвигаемое значение отрицательно, при каждом сдвиге вправо в старший разряд записывается единица, а если положительно – нуль. Не забывайте, сдвиг, выполняемый операторами сдвига, не является циклическим, т.е. при сдвиге как вправо, так и влево крайние биты теряются, и содержимое потерянного бита узнать невозможно.

Операторы сдвига работают только со значениями целочисленных типов, например, символами , целыми числами и длинными целыми числами . Они не применимы к значениям с плавающей точкой.

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

Следующая программа наглядно иллюстрирует результат использования операторов сдвига.

 

 

Результаты выполнения этой программы таковы.

 

Оператор "знак вопроса"

 

Одним из самых замечательных операторов C++ является оператор "?" . Оператор "?" можно использовать в качестве замены if ‑else‑инструкций, употребляемых в следующем общем формате.

 

 

Здесь значение, присваиваемое переменной, зависит от результата вычисления элемента условие , управляющего инструкцией if .

Оператор "?" называется тернарным, поскольку он работает с тремя операндами. Вот его общий формат записи:

 

 

Все элементы здесь являются выражениями. Обратите внимание на использование и расположение двоеточия.

Значение ? ‑выражения определяется следующим образом. Вычисляется Выражение1 . Если оно оказывается истинным, вычисляется Выражение2 , и результат его вычисления становится значением всего ? ‑выражения. Если результат вычисления элемента Выражение1 оказывается ложным, значением всего ? ‑выражения становится результат вычисления элемента Выражение3 . Рассмотрим следующий пример.

 

 

Здесь переменной x будет присваиваться значение 0 до тех пор, пока значение переменной count не станет меньше или равно нулю. Аналогичный код (но с использованием if‑else‑инструкции) выглядел бы так.

 

 

А вот еще один пример практического применения оператора ? . Следующая программа делит два числа, но не допускает деления на нуль.

 

 

Здесь, если значение переменной j не равно нулю, выполняется деление значения переменной i на значение переменной j , а результат присваивается переменной result . В противном случае вызывается обработчик ошибки деления на нуль div_zeго() , и переменной result присваивается нулевое значение.

 


Дата добавления: 2018-09-22; просмотров: 685; Мы поможем в написании вашей работы!

Поделиться с друзьями:






Мы поможем в написании ваших работ!