Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Керниган, Ричи. Язык C.docx
Скачиваний:
5
Добавлен:
05.05.2019
Размер:
377.71 Кб
Скачать

2.9. Побитовые логические операции

В языке предусмотрен ряд операций для работы с битами;

эти операции нельзя применять к переменным типа FLOAT или

DOUBLE.

& Побитовое AND

\! Побитовое включающее OR

^ побитовое исключающее OR

<< сдвиг влево

>> сдвиг вправо

\^ дополнение (унарная операция)

"\" иммитирует вертикальную черту.

Побитовая операция AND часто используется для маскирования

некоторого множества битов; например, оператор

C = N & 0177

передает в 'с' семь младших битов N , полагая остальные рав-

ными нулю. Операция 'э' побитового OR используется для вклю-

чения битов:

C = X э MASK

устанавливает на единицу те биты в х , которые равны единице

в MASK.

Следует быть внимательным и отличать побитовые операции

& и 'э' от логических связок && и \!\! , Которые подразуме-

вают вычисление значения истинности слева направо. Например,

если х=1, а Y=2, то значение х&Y равно нулю , в то время как

значение X&&Y равно единице./почему?/

Операции сдвига << и >> осуществляют соответственно

сдвиг влево и вправо своего левого операнда на число битовых

позиций, задаваемых правым операндом. Таким образом , х<<2

сдвигает х влево на две позиции, заполняя освобождающиеся

биты нулями, что эквивалентно умножению на 4. Сдвиг вправо

величины без знака заполняет освобождающиеся биты на некото-

рых машинах, таких как PDP-11, заполняются содержанием зна-

кового бита /"арифметический сдвиг"/, а на других - нулем

/"логический сдвиг"/.

Унарная операция \^ дает дополнение к целому; это озна-

чает , что каждый бит со значением 1 получает значение 0 и

наоборот. Эта операция обычно оказывается полезной в выраже-

ниях типа

X & \^077

где последние шесть битов х маскируются нулем. Подчеркнем,

что выражение X&\^077 не зависит от длины слова и поэтому

предпочтительнее, чем, например, X&0177700, где предполага-

ется, что х занимает 16 битов. Такая переносимая форма не

требует никаких дополнительных затрат, поскольку \^077 явля-

ется константным выражением и, следовательно, обрабатывается

во время компиляции.

Чтобы проиллюстрировать использование некоторых операций

с битами, рассмотрим функцию GETBITS(X,P,N), которая возвра-

щает /сдвинутыми к правому краю/ начинающиеся с позиции р

поле переменной х длиной N битов. мы предполагаем , что

крайний правый бит имеет номер 0, и что N и р - разумно за-

данные положительные числа. например, GETBITS(х,4,3) возвра-

щает сдвинутыми к правому краю биты, занимающие позиции 4,3

и 2.

GETBITS(X,P,N) /* GET N BITS FROM POSITION P */

UNSIGNED X, P, N;

{

RETURN((X >> (P+1-N)) & \^(\^0 << N));

}

Операция X >> (P+1-N) сдвигает желаемое поле в правый конец

слова. Описание аргумента X как UNSIGNED гарантирует, что

при сдвиге вправо освобождающиеся биты будут заполняться ну-

лями, а не содержимым знакового бита, независимо от того, на

какой машине пропускается программа. Все биты константного

выражения \^0 равны 1; сдвиг его на N позиций влево с по-

мощью операции \^0<<N создает маску с нулями в N крайних

правых битах и единицами в остальных; дополнение \^ создает

маску с единицами в N крайних правых битах.

Упражнение 2-5

---------------

Переделайте GETBITS таким образом, чтобы биты отсчитыва-

лись слева направо.

Упражнение 2-6

---------------

Напишите программу для функции WORDLENGTH(), вычисляющей

длину слова используемой машины, т.е. Число битов в перемен-

ной типа INT. Функция должна быть переносимой, т.е. Одна и

та же исходная программа должна правильно работать на любой

машине.

Упражнение 2-7

---------------

Напишите программу для функции RIGHTROT(N,B), сдвигающей

циклически целое N вправо на B битовых позиций.

Упражнение 2-8

---------------

Напишите программу для функции INVERT(X,P,N), которая

инвертирует (т.е. Заменяет 1 на 0 и наоборот) N битов X, на-

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