- •Действия: что делает программа Глава 2 Выражения
- •Арифметические операторы
- •Замечание
- •Операторы отношений
- •Логические операторы
- •Оператор отрицания
- •Операторы инкремента и декремента
- •Поразрядные операторы
- •Поразрядный оператор исключающего или
- •Сдвиг битов влево
- •Дополнение до единицы
- •Сомр 44 0х002с 0000000000101100
- •Операторы присваивания
- •Выражения значений
- •Приоритеты операторов
Поразрядные операторы
Подобно всем двоичным компьютерам, PC обрабатывают числа, представленные в двоичной системе счисления. Двоичные разряды, или биты, в таких числах, как 1011, полностью соответствуют переключателям внутри компьютерной памяти, работающим по принципу "включено - выключено": бит, равный 0, означает "выключено", а бит, равный 1, - "включено".
Чтобы увеличить скорость компьютера, процессор выполняет чтение, запись и передачу информации не по одному биту, а по группам, представляющим собой 8-битовые байты или 16-битовые слова. С -программы могут обрабатывать такие значения непосредственно в двоичном коде.
Шесть поразрядных операторов выполняют булевы логические операции, названные по имени английского математика Джорджа Буля (1815-1864). В табл. 2.3 сведены все поразрядные операторы языка С.
Таблица 2.3. Поразрядные операторы
Оператор
|
Описание
|
Пример
|
|
&
|
Поразрядное И
|
С = А & В;
|
|
1
|
Поразрядное ИЛИ
|
С = А | В;
|
|
^
|
Поразрядное исключающее ИЛИ
|
С = А ^ В;
|
|
<<
|
Сдвиг битов влево
|
С = А << В;
|
|
>> |
Сдвиг битов вправо ———————————————л————————————————
|
С = А >> В;
|
,
|
~
|
Дополнение до 1, или поразрядное отрицание
|
С = ~ А;
|
|
Первые три поразрядных оператора из табл. 2.3 объединяют два операнда в соответствии с правилами логического И (&), логического ИЛИ (|) и исключающего ИЛИ (^ ). Следующие два оператора, << и >>, сдвигают разряды влево и вправо. Оператор - инвертирует биты значения операнда, заменяя каждый 0 на 1 и каждую 1 на 0; получившееся в результате значение называется дополнением до единицы.
Следующие разделы продемонстрируют каждую операцию из табл. 2.3, что, возможно, поможет вам понять обработку битов в языке С.
Отображение значений в двоичном формате
Функция Borland С printf() может отображать значения в разных форматах, но, к сожалению, двоичный формат не поддерживается. Прежде чем рассмотреть работу поразрядных операторов, необходимо найти способ отображения значений в двоичном формате.
Листинг 2.3 восполняет этот пробел. Однако программа PBIN.C содержит пока еще не рассмотренные элементы программирования, и поэтому здесь они объясняться не будут. Вы просто введите этот листинг и сохраните его под именем PBIN.C. Листинги 2.4-2.9 включают этот файл для отображения значений в двоичном формате.
Замечание
PBIN.C - не законченная программа: вы не сможете скомпилировать и выполнить ее. Вместо этого вы должны скомпилировать и выполнить другие программы, использующие этот файл.
Листинг 2.3. PBIN.C (включаемый файл для отображения двоичных значений)
______________________________________________________________
1: void pbinc(unsigned char n)
2: {
3: int i;
4: for(i =0; i < 8; i++) {
5: if (n & 0х80)
6: putc( '1' , stdout);
7: else
8: putc('0', stdout);
9: n = n << 1;
10: }
11: }
12:
13: void pbin(unsigned int n)
14: {
15: pbinc(n / 256);
16: pbinc(n % 256);
17: putc( '\n' , stdout);
18: }
————————————————————————————
Замечание
Любая программа, включающая файл PBIN.C, должна включать и стандартный заголовочный файл STDIO.H.
Поразрядный оператор И
Листинг 2.4 демонстрирует поразрядный оператор И (&). (Буква Т в названии программы символизирует слово тест). Скомпилируйте и выполните программу. По приглашению введите два числа, разделенных одним пробелом (например, 1234 и 15). Нажмите <Enter> для получения исходных значений и результата оперaторa И в десятичном, шестнадцатеричном и двоичном представлениях.
Листинг 2.4. TAND.C (поразрядный оператор И)
_____________________________________________________
1: #include <stdio.h>
2: #include "pbin.c"
3:
4: main()
5: {
6: unsigned v1, v2, v3;
7:
8: printf(“Enter values to AND: (ex: 1234 15) ");
9: scanf("%u %u", &v1, &v2);
10: v3 = v1 & v2;
11: printf(" %5u %#06x ", v1, v1); pbin(v1);
12: printf('AND %5u %#06x ", v2, v2); pbin(v2);
13: printf(“=========================="=======\n");
14: printf(" %5u %#06x ", v3,v3); pbin(v3);
15: return 0;
16: }
_______________________________________________________
Строка 10 присваивает беззнаковой переменной v3 результат выражения vl & v2. Строки 11-14 отображают исходные значения и конечный результат. (Операторы в этих строках вызывают функцию pbin() из файла PBIN.C, включенного для отображения двоичных цифр в строке 2).
В табл. 2.4 перечислены правила, по которым работает поразрядная операция И. Данная таблица отображает результат (С) применения поразрядного оператора И (&) к двум однобитовым операндам (А и В). В соответствии с правилами для поразрядной операции И результат будет равен 1 только в том случае, когда оба операнда равны 1; в противном случае результат будет равен 0.
Как правило, поразрядный оператор И используется для маскирования части значения таким образом, чтобы в результат попала только часть этого значения. Чтобы убедиться в этом, запустите программу TAND.C введите два числа 1021 и 15 (разделенные одним пробелом). Программа отобразит следующее:
1021 0х0Зfd 0000001111111101
AND 15 0x000f 0000000000001111
====================================
13 0x000d 0000000000001101
Таблица 2.4. Поразрядная операция И
А
|
&
|
B
|
==
|
C |
0
|
&
|
0
|
==
|
0
|
0
|
&
|
1
|
==
|
0
|
1
|
&
|
0
|
==
|
0
|
1
|
&
|
1
|
==
|
1
|
Число 15 в двоичном коде равно 1111 (без ведущих нулей). При использовании в качестве операнда оператора И это число называется маской. Разряды значения, соответствующие 1 в маске, попадают в результат разряды, соответствующие 0, обнуляются в результате. Они сбрасываются в 0, безотносительно к их первоначальному значению.
На рис. 2.1 показано действие логической операции И. Разряды маски, равные 1, позволяют разрядам операнда попадать в результат без изменения. Разряды маски, равные 0, блокируют соответствующие разряды операнда, сбрасывая их также в 0 и в результате.
Рис. 2.1. Результат логической операции И над операндом и маской
Замечание
На рис. 2.1 разряды нумеруются справа налево. По соглашению самый младший разряд (крайний справа) имеет нулевой номер. С возрастанием старшинства разряда возрастает его номер. Таким образом, разряд с номером 7 является самым старшим разрядом в 8 -разрядном двоичном значении. Разряд с номером 15 - самый старший в 16-разрядном двоичном значении и т.д.
Поразрядный оператор ИЛИ
Листинг 2.5 демонстрирует поразрядный оператор ИЛИ (|). Скомпилируйте и выполните программу. По приглашению введите два числа, разделенных одним пробелом.
Листинг 2.5. TOR.С (поразрядный оператор ИЛИ)
________________________________________________________
1: #include <stdio.h>
2: #include "pbin.c"
3:
4: main()
5: {
6: unsigned v1, v2, v3;
7:
8: printf(“Enter values to OR inclusively: (ex: 1234 15) ");
9: scanf("%u %u", &v1, &v2);
10: v3 = v1 | v2;
11: printf(" %5u %#06x ", v1, v1); pbin(v1);
12: printf(“OR %5u %#06x ", v2, v2); pbin(v2);
13: printf("===::====================::===========\n");
14: printf(" %5u %#06x ", v3, v3); pbin(v3);
15: return 0;
16: }
_____________________________________________________
Правила для поразрядной операции ИЛИ дополняют правила для поразрядной операции И. В табл. 2.5 перечислены результаты поразрядной операции ИЛИ для всех комбинаций двух одноразрядных операндов. Результат будет равен 0 только в том случае, если оба операнда равны 0; в противном случае, т.е. если хотя бы один из операндов (или оба сразу) равен 1, результат будет равен 1.
Таблица 2.5. Поразрядная операция ИЛИ
А
|
| |
В
|
== |
C |
0
|
| |
0
|
==
|
0
|
0
|
| |
1
|
==
|
1
|
1
|
| |
0
|
==
|
1
|
1
|
| |
1
|
==
|
1
|
Поразрядный оператор ИЛИ часто используется для вставки (или включения) нужных разрядов в значения. Убедитесь в этом, запустив программу TOR и введя числа 153 и 5. Программа отобразит следующее:
153 0х0099 0000000010011001
OR 5 0х0005 0000000000000101
=================================
157 0x009d 0000000010011101
Рис. 2.2. Результат логической операции ИЛИ над операндом и маской
Результат (157) в двоичном формате содержит все установленные в 1 разряды исходного числа (153) плюс новые (единичные) разряды из маски (5). Таким образом, единицы из маски будут включены в значение результата для любого значения операнда. Нулевые разряды маски позволят "попасть" в результат исходным разрядам операнда. Сравните полученный результат с результатами поразрядного оператора И, "пропускающего" в результатr только те разряды операнда, которые соответствуют "единицы" маски.
На рис. 2.2 показано действие оператора ИЛИ. Разряды маски, равные 1, устанавливают равными 1 соответствующие разряды результата невзирая на значения соответствующих разрядов операнда. Разряды маски, равные 0, позволяют разрядам операнда попадать в результат без изменения.