- •Лекция 4 Операции и выражения
- •Понятие выражения и операции
- •Классификация операций
- •Приоритеты (ранги) операций
- •Арифметические операции
- •Примеры использования арифметических операций Выделение цифр в целом числе
- •Выделение цифр в вещественном числе
- •Арифметические операции над переменными символьного типа
- •Операции инкремента и декремента
- •Особенности выполнения операций инкремента и декремента
- •Операции присваивания
- •Примеры использования
- •Операции отношения
- •Логические операции
- •Особенности выполнения логических операций
- •Примеры использования логических операций
- •Логические выражения и примеры их записи
- •Поразрядные логические операции
- •Примеры выполнения поразрядных логических операций:
- •Операции поразрядного сдвига
- •Дополнительные операции Операции доступа к компонентам структурированного объекта
- •Операции доступа к адресуемым компонентам классов
- •Определение размера sizeof
- •Вызов функции ( )
- •Индексация [ ]
- •Операция запятая ,
- •Операция расширения области видимости ::
- •Преобразование типа
- •Правила преобразования типов
- •Примеры преобразования типов
- •2. Особенности преобразования типов int и double:
- •7. Проанализируйте преобразование типов в операторах присваивания:
- •8. Приведение типа в случае использования указателей:
- •9. Преобразование старшего типа к младшему удобно использовать для выделения отдельных частей переменной или константы:
- •10. С помощью приведения типа можно получить дробную часть числа:
- •Программирование вычисления алгебраических выражений
- •Определение первого символа вводимого значения
- •Контроль правильности ввода значения переменной
- •Основные встроенные (стандартные) функции
- •Пример вычисления по формуле
- •Замечания по программированию алгебраических выражений
- •Особенности представления чисел по двоичному основанию*
- •Особенности выполнения арифметических операций над вещественными числами*
- •Операции умножения и деления
- •Операции сложения и вычитания
- •Особые ситуации Ошибки округления
- •Ошибки переполнения
- •Потеря (исчезновение) порядка
- •Катастрофическая потеря порядка
- •Потеря значащих цифр
- •Особенности выполнения операций отношения (сравнения)
- •Обратить внимание
- •Правила работы с данными вещественных типов
Поразрядные логические операции
Обратите внимание, на специфические операции, определенные в C++ только для целочисленных типов и для выражений, приводимых к целому типу, – поразрядные логические операции. Их распространенное применение – обработка информации в регистрах, области системных данных компьютера, от различных его устройств, когда в силу ограниченности пропускной способности каналов информация упаковывается в байт, слово и т.д., а также – кодируется некоторым образом.
Результат поразрядной логической операции – целое число. Биты результата формируются из битов операндов поразрядно по тем же правилам, что и для логических операций. Только операндами и результатами вместо true является 1, а вместо false – 0. Операции выполняются слева направо, кроме операции поразрядного отрицания.
Таблица6.2. Значения поразрядных логических операций
-
A
B
результат поразрядных операций
~ A
&
|
^
0
0
1
0
0
0
0
1
1
0
1
1
1
0
0
0
1
1
1
1
0
1
1
0
операция |
содержание |
~ |
поразрядное отрицание (поразрядная инверсия, дополнение до 1) |
& и |
1 во всех разрядах, где у операндов 1 |
| или |
1 во всех разрядах, где один или второй операнды имеют 1 |
^ исключающее или |
1 во всех разрядах, где операнды имеют разные двоичные значения |
Примеры выполнения поразрядных логических операций:
Пример 1.
12 & 22 = 4, так как:
1210 = С16 = 000011002 (для типа char)
(поразрядное умножение - &) *
2210 =1616 = 000101102
__________
000001002 = 410
Пример 2.
char i, j, k; …… i=5; j=3; k= i & j;
k==1, т.к. в двоичной системе имеем: 00000101(i) & 00000011(j) = 00000001 (k).
Пример 3.
12 | 22 = 30, так как:
1210 = С16 = 000011002 (для типа char)
(поразрядное сложение - or) +
2210 =1616 = 000101102
__________
000111102 = 1* 24 +1*23+ 1*22+ 1* 21 =3010;
Пример 4.
12 ^ 22 = 26, так как:
1210 = С16 = 000011002 (для типа char)
(операция ^)
2210 =1616 = 000101102
__________
000110102 = 1* 24 +1*23+ 1* 21 =2610;
Пример 5.
Операция Y = X & 15 или ее аналог Y = X & $F – выделяет 4 младших разряда переменной Х (типа char), т.к. $F = 15 = 00001111. Старшие разряды обнуляются независимо от их значения, младшие – сохраняются.
Пример 6.
От прибора в ЭВМ поступает 16-разрядный код (справа налево номера от 0 до 15). Допустим, в разрядах 0-4 находится информация от первого датчика, 5-11 – от датчика 2, с 12 по 14 – от датчика 3. Рассмотрим алгоритм выделения информации от каждого из датчиков:
int Х, XX, x1, x2, x3; {ХX – исходная интегрированная информация} {x1, x2, x3 – выделенная информация от датчиков} . . . . . X = XX; x1 = X & 31; {выделяются разряды с 0 по 4 –- 31 =0000 0000 0001 1111}
X = X / 32; {происходит сдвиг Х на 5 разрядов вправо, }
{ аналог – команда Х >> 5}
x2 = X & 127; {выделяются очередные 7 разрядов, бывшие разряды 5-11}
{127 = $7F = 0000 0000 0111 1111}
X = X / 128; {производится сдвиг вправо очередных 7-и разрядов}
x3 =X & 7; {выделяются младшие 3 разряда, бывшие 12 - 14}
Пример 7.
Состояние 3-х кнопок мыши возвращается в переменной Button (тип char) в такой последовательности: левая, правая, средняя в разряды 0 –2. Тогда для анализа состояния кнопок мыши можно использовать операторы:
LeftButton = (Button & 1) == 1;
RightButton = (Button & 2) == 2;
LeftRightButton = (Button & 3) == 3;
MiddleButton = (Button & 4) == 4;
LeftMiddleButton = (Button & 5) == 5;
Пример 8.
С помощью поразрядной логической операции & легко найти остаток от деления операндов типа unsigned int на значения, кратные двум.
Например, определение остатка от деления операнда D типа unsigned int на 2, 4, 8, 16 и т.д. требует поразрядной логической операции & делимого D соответственно с масками 0х01, 0х03, 0х07, 0х0f, 0x1f и т.д. Другими словами, выделяются младшие биты числа, а остальные устанавливаются в 0. Это наиболее быстрый способ выделения остатка.
unsigned D, mask = 0x01; //(при делении на 2); 0x03 (на 4); 0x07 (на 8); 0x0f (на 16); 0x1f (на 32);
D =7;
D & mask; //- значение разряда, который «уходит» при делении на 2 последний раз
00000111 - это 7
00000001 - для 2-х
------------
00000001 - это 1 (остаток от деления 7 на 2, результат операции 7 & 2)
00000111 - это 7
00000011 - для 4-х
------------
00000011 - это 3 (остаток от деления 7 на 4, результат операции 7 & 4)
Пример 9.
С помощью поразрядной логической операции & можно проверить наличие единицы в любом разряде:
проверить наличие единицы в бите №4 переменной х типа char поможет логическое выражение: (х & 16) == 16;
проверить наличие единицы в битах №4, №2, №1 переменной х типа char поможет логическое выражение: (х & 22) == 22;
Пример 10.
С помощью поразрядной логической операции & можно «выключить» значение любого бита:
выключить бит №2 переменной х типа char (при неизменном значении других битов) поможет логическое выражение: х & 251 (255 – это единицы во всех разрядах, логическое выражение (х & 255) – оставит без изменения значения всех битов, бит 2 имеет значение 4, х & (255-4) – обнулит только бит номер 2;
Пример 11.
С помощью поразрядной логической операции | можно «включить» значение любого бита:
включить бит №2 переменной х типа char (при неизменном значении других битов) поможет логическое выражение: х | 4;
включить биты №4, №2, №1, №0 переменной х типа char (при неизменном значении других битов) поможет логическое выражение: х | 23;
Что напечатает программа:
#define PRINT(int) printf(“int=%d\n”, int)
int x, y, z);
x=03; y=02; z=01;
PRINT(x | y & z); |
(0011 | (0010 & 0001))=(0011|0000)=0011=3 |
PRINT(x | y & ~z); |
(0011 | (0010 & 1110))=(0011|0010)=0011=3 |
PRINT(x ^ y & ~z); |
(0011^(0010 & 1110))=(0011^0010)=0001=1 |
PRINT(x & y && z); |
((0011&0010)&&0001=(0010&&0001)=истина |