Шрифт:
значение переменной new_number_one будет равно 192 (двоичный код 00000000 11000000), а значение переменной new_number_two — 3 (двоичный код 00000000 00000011).
Рассмотрим два других логических оператора: поразрядное логическое И и поразрядное логическое ИЛИ.
Символ | Операция | Пример |
---|---|---|
& | Логическое И | *(0x0023) & 0x57 |
| | Логическое ИЛИ | *(0x0000) | 0x35 |
Все числа, записанные в колонке «Пример», представлены в шестнадцатеричном коде, поскольку содержат префикс 0x. Унарный оператор * показывает, что действие будет производиться над содержимым ячейки памяти с физическим адресом, значение которого в шестнадцатеричном коде указано в скобках.
Результат операции логического И над двумя двоичными числами 01011100 и 11000111 будет равен :
Результат операции логическое ИЛИ над теми же числами:
В каких задачах управления используются эти логические операторы? В прикладных программах (т.е. программах управления) часто приходится изменять сигналы на отдельных линиях портов ввода/вывода. Регистры данных портов расположены по строго определенным в техническом описании физическим адресам. Так для того, чтобы сконфигурировать все линии порта PORT A на ввод, необходимо в регистр направления передачи порта DDRA (физический адрес 0x0002) записать все нули. Это может быть выполнено под управлением следующей строки:
Если порт Port A настроен на вывод, то установить линию PTA7 в единицу без изменения состояния остальных линий порта можно посредством следующей записи:
Выше использована сокращенная форма записи выражения:
Выражение возвращает результат операции поразрядного логического ИЛИ числа 0x80 (10000000 в двоичной системе счисления) и содержимого порта PortA. После операции старший бит Port A будет установлен в 1, остальные биты останутся без изменения.
Аналогично, старший бит порта Port A может быть установлен в 0 (сброшен) посредством записи выражения:
Это выражение аналогично другому, более понятному для начального уровня освоения языка Си:
Для установки в 0 старшего разряда порта Port A содержимое порта побитно логически умножается на константу 0x7F (01111111 в двоичном коде). В результате старший бит становится равным 0, а остальные биты остаются без изменения. Запись ~0х80 в первом выражении предписывает перед выполнением операции логического И взять инверсию константы 0x80 (10000000), которая будет равна 0x7F (01111111). Вторая запись более понятна на начальном этапе программирования на Си, в то время как первая запись позволяет использовать одну и ту же константу в выражениях по установки и сбросу бита, что в практическом программировании удобно.
Операцию поразрядного логического И также следует использовать, если необходимо проверить, установлены или сброшены биты порта с определенными номерами. Например, приведенный ниже фрагмент программы производит чтение регистра данных порта Port A, логически умножает его содержимое на константу 0x81 и сравнивает полученный результат с нулем. Если условие равенства нулю выполняется, то это означает, что биты 7 и 0 порта Port A одновременно равны нулю, и следует выполнить действия, которые описаны операторами в фигурных скобках. Если хотя бы один бит PTA7 или PTA0 не равен нулю, то условие ((PORTA & 0х81) == 0) не выполняется, и операторы в фигурных скобках будут пропущены при исполнении.
В качестве примера использования оператора ИСКЛЮЧАЮЩЕГО ИЛИ приведем выражение для инвертирования значения бита 7 порта Port A:
Операторы группы унарных операций. Поскольку операторы инкремента и декремента были рассмотрены выше, основное внимание уделим операторам указателя и косвенной адресации (см. табл. 3.2). Для иллюстрации действия этих операторов рассмотрим следующий пример. Определим три целочисленных переменных с именами num, address, и new_num:
Также предположим, что переменная num расположена в памяти по адресу 0x2000. Запишем следующее выражение:
Результатом исполнения выражения будет присвоение переменной address значения адреса переменной num, т.е. новое значение переменной address будет равно 0x2000.
Запишем новое выражение:
Результатом выполнения этого выражения будет присвоение переменной new_num значения, которое содержится в ячейке памяти, адрес которой равен текущему значению переменной address. Поскольку содержимое address равно 0x2000, т.е. адресу переменной num, то рассматриваемое выражение в нашем случае эквивалентно выражению: