Обратите внимание на то, что в операторах с вызовами метода println () логические операторы заключены в круглые скобки. Эти скобки необходимы для соблюдения предшествования операторов. В частности, арифметический оператор + имеет более высокий порядок предшествования, чем логические операторы.
Скомпилируйте программу и запустите ее на выполнение, чтобы вывести на экран следующий результат:P Q AND OR XOR NOT true true true true false false true false false true true false false true false true true true false false false false false true
Попробуйте видоизменить программу таким образом, чтобы вместо логических значений true и false отображались значения 1 и 0. Это потребует больших усилий, чем кажется на первый взгляд! Выражения
Операторы, переменные и литералы являются составными частями выражений. Выражением в Java может стать любое допустимое сочетание этих составных частей. Выражения должны быть уже знакомы вам по предыдущим примерам программ. Более того, вы изучали их в школьном курсе алгебры. Но некоторые их особенности все же нуждаются в обсуждении. Преобразование типов в выражениях типов в выражениях
В выражении можно свободно употреблять два или несколько типов данных, при условии их совместимости друг с другом. Например, в одном выражении допускается применение типов short и long, поскольку оба типа являются числовыми. Когда в выражении употребляются разные типы данных, они преобразуются в один и тот же тип по принятым в Java правилам продвижения типов.
Сначала все значения типа char, byte и short продвигаются к типу int. Затем все выражение продвигается к типу long, если хотя бы один из его операндов принадлежит к типу long. Далее все выражение продвигается к типу float, если хотя бы один из операндов относится к типу float. А если какой-нибудь из операндов относится к типу double, то результат также относится к типу double.
Очень важно иметь в виду, что правила продвижения типов применяются только к значениям, над которыми выполняются действия по мере вычисления выражения. Так, если значение переменной типа byte при вычислении выражения продвигается к типу int, за пределами выражения эта переменная будет по-прежнему относиться к типу byte. Следовательно, продвижение типов затрагивает только вычисление выражения.
Но продвижение типов может иногда привести к неожиданным результатам. Если, например, в арифметической операции используются два значения типа byte, то про исходит следующее. Сначала операнды типа byte продвигаются к типу int. А затем выполняется операция, дающая результат типа int. Следовательно, результат выполнения операции, в которой участвуют два значения типа byte, будет иметь тип int. Но ведь это не тот результат, который можно было бы с очевидностью предположить. Рассмотрим следующий пример программы: // Неожиданный результат продвижения типов! class PromDemo { public static void main(String args[]) { byte b; int i; b = 10; // В данном случае приведение типов не требуется, так как // результат вычисления выражения уже относится к типу int. i = b * b; b = 10; // А в этом случае приведение типов требуется для // присваивания значения int переменной типа byte! b = (byte) (b * Ь); // cast needed!! System.out.println("i and b: " + i + " " + b); } }
Как ни странно, но когда результат вычисления выражения bb присваивается обратно переменной Ь, то возникает потребность в приведении к типу byte! Объясняется это тем, что в выражении bb значение переменной b продвигается к типу int и поэтому не может быть присвоено переменной типа byte без приведения типов. Имейте это обстоятельство в виду, если получите неожиданное сообщение об ошибке несовместимости типов в выражениях, которые, на первый взгляд, кажутся совершенно правильными.
Аналогичная ситуация возникает при выполнении операций с символьными операндами. Например, в следующем фрагменте кода требуется обратное приведение к типу char, поскольку операнды chi и ch2 в выражении продвигаются к типу int: char chi = 'a', ch2 = ' b'; chi = (char) (chi + ch2);
Без приведения типов результат сложения операндов chi и ch2 будет иметь тип int, и поэтому его нельзя присвоить переменной типа char.
Приведение типов необходимо не только при присваивании значения переменной. Рассмотрим в качестве примера следующую программу. В ней приведение типов выполняется для того, чтобы дробная часть числового значения типа double не была утеряна. В противном случае операция деления будет выполняться над целыми числами. // Приведение типов для правильного вычисления выражения, class UseCast { public static void main(String args[]) { int i; for(i = 0; i < 5; i++) { System, out .println (i + " / 3: 11 + i / 3) ; System.out.println(i + " / 3 with fractions: " + (double) i / 3); System.out.println(); } } }
Ниже приведен результат выполнения данной программы. 0 / 3: 0 0/3 with fractions: 0.0 1 / 3: 0 1/3 with fractions: 0.3333333333333333 2 / 3: 0 2/3 with fractions: 0.6666666666666666 3/3: 1 3/3 with fractions: 1.0 4 / 3: 1 4/3 with fractions: 1.3333333333333333 Пробелы и круглые скобки
Для того чтобы сделать выражения в коде Java более удобными для восприятия, в них можно использовать символы табуляции и пробелы. Например, ниже приведены два варианта одного и того же выражения, но второй вариант читается гораздо легче. х=10/у*(127/х) ; х = 10 / у * (127/х);
Круглые скобки повышают порядок предшествования содержащихся в них операций. (Аналогичное правило применяется и в алгебре.) Избыточные скобки допустимы. Они не приводят к ошибке и не замедляют выполнение программы. В некоторых случаях лишние скобки даже желательны. Они поясняют порядок вычисления выражения как для вас, так и для тех, кто будет разбирать исходный код вашей программы. Какое из приведенных ниже двух выражений воспринимается легче? х = y/3-34*temp+127 ; х = (у/3) - (34*temp) + 127; Упражнение для самопроверки по материалу главы 2
Почему в Java строго определены диапазоны допустимых значений и области действия простых типов?
Что собой представляет символьный тип в Java и чем он отличается от символьного типа в ряде других языков программирования?
Переменная типа boolean может иметь любое значение, поскольку любое ненулевое значение интерпретируется как истинное. Верно или неверно?
Допустим, результат выполнения программы выглядит следующим образом: One Two Three Напишите строку кода с вызовом метода println (), где этот результат выводится в одной символьной строке.
Какая ошибка допущена в следующем фрагменте кода:for(i = 0; i < 10; i++) { int sum; sum = sum + i; } System.out.println("Sum is: " + sum);
Поясните отличие между префиксной и постфиксной формами оператора инкремента.
Покажите, каким образом укороченный логический оператор И может предотвратить деление на нуль.
К какому типу продвигаются типы byte и short при вычислении выражения?
Когда возникает потребность в явном приведении типов?
Напишите программу, которая находила бы простые числа в пределах от 2 до 100.
Оказывают ли лишние скобки влияние на эффективность выполнения программ?
Определяет ли кодовый блок область действия переменных?
Глава 3 Управляющие операторы
Основные навыки и понятия
Ввод символов с клавиатуры
Полная форма условного оператора if
Применение оператора switch
Полная форма цикла for
Применение цикла while
Применение цикла do-while
Применение оператора break для выхода из цикла
Использование оператора break в качестве оператора goto
Применение оператора continue
Вложенные циклы
В этой главе вы ознакомитесь с операторами, управляющими ходом выполнения программы. Существуют три категории управляющих операторов: операторы выбора,к числу которых относятся операторы if и switch, итерационные операторы, в том числе операторы цикла for, while, do-while, а также операторы перехода, включая break, continue и return. Все эти управляющие операторы, кроме оператора return, обсуждаемого далее в книге, подробно рассматриваются в этой главе, в начале которой будет показано, каким образом организуется простой ввод данных с клавиатуры. Ввод символов с клавиатуры