|
Программирование >> Унарные и бинарные операторы
Логические операторы Для задачи суммирования чисел, решенной нами в предыдущем разделе, было достаточно проверять при каждом обороте цикла всего одно условие - 1<=N. Но так бывает далеко не всегда. Случается, что какое-то действие нужно выполнить при соблюдении двух и большего числа условий. Например, для попадания в какой-то интервал переменная должна быть одновременно больше чего-то одного и меньше чего-то другого. Поэтому в языке С++ есть специальные логические операторы, I юмогающие записьшать сложные условия. Например, условие попадания числа х в интернат (9,10) записьшается так: х>9 && X <10: В нем сначала проводятся сравнения х>9 и х<10, потому что приоритет операторов о, выше, чем оператора &&, а затем с результатами этих сравнений работает оператор &&. Предположим, что проверяемое число от- Впрочем, смогрите задачу 3.3. носится к типу double и равно 9.5. Тогда результатом обоих сравнений будет истина , а если аргументы, соединяемые оператором &&, истинны, то таковым будет и окончателы[ый результат. Но если хотя бы одно условие (х>9 или х<10 ) не выполняется, значение выражения х>9 && X <10 будет ложным. Оператор && называется логмческш* И и дает истину , только если истинны обе величины, участвующие в операции (их enie называют операндами). Причем истиной считается не только единица, но и любое положительное число. Например, результат операции 10 && 20 истинен, а О && 1000 - ложен. Другой оператор из этого семейства (11) называется логическим ИЛИ, он истинен, когда хотя бы один из операндов истинен. То есть 1111=1110+0111=1,0110=0. Наконец, последний логический оператор (!) называется оператором отрицания, он преврап1ает истишюе значение в ложное и наоборот. Значение ! 1000 равно нулю, а значите !0 - единице. Как мы уже поняли, результатов условгюй или логической операции может быть только два: верно-неверно, да-нет и т. д. Логично поэтому ввести специальную переменную, которая имеет всего два значения, а значит, способна хранить результат логической операции. Такие переменные в языке С++ объявляются как bool, например: bool to be: У них всего два значения: true (истина) и f al se (ложь). Впрочем, без всякой 01нибки мож1[0 считать, что true равно едини11е, а fal se - пулю. Рассмотрим листинг 3.4. Листинг 3.4 include <1ostream> using namespace std: int main(){ int a=2.b=3: прололжение бого количества чисел. Нужно только поменят! значение N. Программисты не должны писать одноразовые программы. Ведь программирование - тяжелый труд, и нужно стремиться использовать его результаты многократно. Завершим этот раздел перечислегшем других условных операторов. Легко построить по образу и подобию операторов < (меньше), <= (меиьнге или равно) операторы > (больше), >= (больше или равно). Кроме них есть еще оператор == (равно), значение которого истинно, если две неременные равны, и оператор !-(не равно), его значение истинно, когда переменные различны. Опасные операторы Складывая и умножая переменные, мы до сих пор мало думали о том, что за этим стоит. А ведь сложение переменной типа double с переменной типа int - совсем не то же самое, что сложение двух целочисленных переменных! Переменная double занимает, как правило, больше места в компьютерной памяти, иначе кодируется и способна хранить гигантские числа, которые никак не поместятся в переменной типа int. Значит, перед выполнением арифметической операции переменные нужно привести к одному типу, причем более узкая переменная должна быть преобразована к более широкой . Если говорить о переменных типа int и double, то целочисленная переменная должна быть преобразована к типу double, после чего и выполняется арифметическая операция. Если же переменные однотипны, то вычисление производится сразу, без преобразований. Так, при делении меньшего целого числа на большее получится тоже целое число, равное нулю. И куда не засылай полученный результат, хоть в переменную типа double, он все равно останется нулем. Эту мысль иллюстрирует листинг 3.5, где результат деления двойки на тройку засылается в переменную типа double и затем выводится на экран. Листинг 3.5 #include <iostream> using namespace std; irit main(){ int a=2.b=3: double c=a/b: cout с endl: c=0: c=static cast<double>(a)/b: cout c endl: c-0.66666 } Чтобы получить в результате деления ожидаемую величину 2/3 или в десятичном представлении 0.6666666..., необходимо преобразовать одну из переменных к типу double. Тогда за ней потянется и другая переменная, а в результате получится значение типа doubl е. В языке С++ такое преобразование делается с помощью специального оператора, показанного в предпоследней строке листинга. Оператор состоит из слова static cast, типа, к которому преобразуется неременная, заключенного в феугольные скобки (в нашем случае это <doubl е>), и самого выражения в круглых скобках. Сама переменная типа int при этом не страдает, просто компилятор для хранения ее содержимого выделяет временную переменную типа double. Листинг 3.4 (продолжение) bool 1: 1=а < Ь: cout 1 endl; cout (а < b) endl; } Инструкция cout 1 endl выведет па экран единицу. Тот же результат получится при непосредственном выводе результата операции а<Ь без присвоения его булевой переменной. Но теперь нужно заключить а<Ь в скобки, потому что оператор имеет больший приоритет, и компилятор, если не поставить скобки, поймет последнюю инструкцию профаммы как вывод на экран переменной а (cout а), а дальше вроде бы нужно выполнять операцию cout < b, но с объектом cout это невозможно, и компилятор, выдав сообщение об ошибке, прекратит работу. Задача 3.2. Чему равно выражение to be 11 !to be при разных значениях булевой переменной tobe? Новые типы - новые опасности у меня, как говорится,очень jKuiBHTTa-лант к наблюдению, но только когда уже поздно и когда неприятность уже пронзо1ила. Я. Гашек, Похождения бравого солдата Швейка Арифметические операторы сгаповятся сп(с опаснее, когда увеличивается число доступных типов переменных. До сих пор нам были известны целочисленные переменные тина int и переменные с плавающей точкой (double). Но оказывается, в языке С++ есть много других переменных, с некоторыми из которых нам придется позгшкомиться в этом разделе. Прежде всего нужно понять, что целочисленные переменные делятся на знаковые (к ним относится переменная int) и беззнаковые. Исреме1Н1ые со знаком хранят отрицательные, положительные числа и ноль. Переменные без знака хранят только положительные числа и ноль. Если переменные занимают одно и то же число битов, то их емкость одинакова. Это значит, что пе-реме1П1ая без знака способна хранить большие положительные числа, чем знаковая переменная того же размера. Мы уже знаем, что переменная типа int храни! числа от -2 147 483 648 до 2 147 483 647. Беззнаковая переменная того же размера объявляется особым образом (unsigned int:) и способна хранить числа от О до 4 294 967 295. Псреме1Н1ые со знаком, как и переменные unsigned, состоят из одного и того же невесомого материала - битов, и, взглянув на область памяти, отведенную под них, нельзя догадаться, какая переменная знаковая, какая - нет. Только зная заранее тип переменной, можно понять, что эа число в ней закодировано. Чтобы понять, как кодируются реальные переменные, представим себе область памяти длиной всего в четыре бита. Таких коротких переменных на самом деле не бывает, просто нам будет удобнее па их примере понять принцип кодироваг1ия ч иссл со знаком и без знака. Пусть в пашей переменной все четыре бита равны единице. Возникает вопрос; что за число в ней хранится? Ответ зависит от типа переменной. Если она беззнаковая, тогда для кодировки используется обычный двоичный код, то есть четыре единицы, - а это в десятичном представлении равно: 1 X 2 + 1 X 2 + 1 X 22 + 1 X 23 = 1 + 2 + 4 + 8 - 15. Если же известно, что это переменная со знаком, то в ней хранится -1! Почему? Потому что для кодировки чисел со знаком применяется так называемый двоичный дополнительный код, устроенный так, что прибавление соответствующего положительного числа дает в результате ноль. Чтобы убедиться в этом, попробуем прибавить единицу к числу -1, то есть сложить двоичные числа 1111 и 0001. Напомню правила сложения двоичных чисел:0 + 0 = 0, 0+1 = 1+ 0=1; 1 + 1= 0 (и 1в уме). Применяя их к нашим числам, получим 1111 + 0001 = 10000 - двоичное число 16, а вовсе не ноль. Но ведь единица появляется в несуществующем для нашей перемегпюй пятом разряде - эта единица сваливается с ее левого конца и пропадает, остается желанный ноль! Зная, что сумма двоичного представления отрицательного числа (при размере переменной в 4 бита) и соответствующего положительного равна шестнадцати, легко получить двоичную запись для всех отрицательных чисел. Пусть, например, X - двоичное представление числа -2. Тогда, очевидно, Х + 2 = 16,аХ=14 = = 8 + 4 + 2 + 0= И10. Как правило, двоичный допол-
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |