Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
49
Добавлен:
12.05.2015
Размер:
1.82 Mб
Скачать

Глава 4. Операции 97_

II Беззнаковый сдвиг byte-значения, class ByteUShift {

static public void main(String args [ ]) { char hex[] = {

'0', '!', '2', '3', '4', '5', '6', '7', '8', '91, 'a', 'b', 'c', 'd', 'e1, 'f' };

byte b = (byte) Oxfl; byte с = (byte) (b » 4); byte d = (byte) (b >» 4); byte e = (byte) ((b & Oxff) » 4);

System.out.println(" b = Ox"

+ hex[(b » 4) & OxOf] + hex[b & OxOf]); System.out.println(" b » 4 = Ox"

+ hex[(c » 4) & OxOf] + hex[c & OxOf]); System.out.println(" b >» 4 = Ox"

+ hex[(d » 4) & OxOf] + hex[d & OxOf]);

System.out.println("(b & Oxff) » 4 = Ox"

+ hex[(e » 4) & OxOf] + hex[e & OxOf]); } )

По выводу кажется, будто операция >» ничего не делает, работая с байто­выми операндами. Для этой демонстрации в переменную ь устанавливается произвольное отрицательное byte-значение. Затем с присваивается byte-значение ь, сдвинутое вправо на четыре разряда, что дает Oxff из-за ожи­давшегося расширения знака. Затем d присваивается byte-значение ь, сдви­нутое без знака вправо на четыре, что, по вашим ожиданиям, должно бы быть OxOf, но фактически есть Oxff из-за расширения знака, которое про­изошло, когда ь была расширена перед сдвигом до типа int. Последнее вы­ражение устанавливает в е byte-значение ь (типа byte), маскированное до 8 бит (с помощью операции И) и затем сдвинутое вправо на четыре разряда, что и дает ожидаемое значение OxOf. Обратите внимание, что операция без­знакового сдвига вправо для d не использовалась, т. к. состояние знакового разряда после операции И было известно.

b = Oxfl b » 4 = Oxff b >» 4 = Oxff (b & Oxff) » 4 = OxOf

Поразрядная операция присваивания

Все бинарные поразрядные операции имеют форму, которая объединяет присваивание с поразрядной операцией. Например, два следующих опера-

98 Часть I. Язык Java

тора, которые сдвигают значение вправо на четыре разряда, являются экви­валентными:

а = а » 4; а »= 4;

Аналогично, следующие два оператора, которые присваивают переменной а значение поразрядного выражения a or ь, являются эквивалентными:

а = а | Ь; а |= Ь;

Представленная ниже программа создает несколько целых переменных и затем для манипулирования ими использует сокращенную форму присваи­вания с поразрядными операциями:

class OpBitEquals {

public static void main(String args[]) { int a = 1; int b = 2; int с = 3;

a |= 4; b »= 1;

с «= 1;

a A= c;

System.out.println("a = " + a); System.out.println("b = " + b); System.out.println("c = " + c); } }

Вывод этой программы:

a = 3 b = 1 с = 6

Операции отношений

Операции отношений1 (relational operators) определяют отношения, которые один операнд имеет к другому. В частности, они определяют равенство и упорядочивания. В Java используются операции отношений, представлен­ные в табл. 4.4.

1 В отечественной практике часто используется термин операции сравнения. — Примеч. пер.

Глава 4. Операции 99

Таблица 4.4. Операции отношений

Операция Результат

Равно != Неравно > Больше чем < Меньше чем >= Больше чем или равно <= Меньше чем или равно

Результат этих операций — значение типа boolean. Операции отношений часто используются в выражениях, которые управляют условными операто­рами и различными операторами цикла.

Данные любых Java-типов, включая целые числа, числа с плавающей точ­кой, символы и булевские переменные, можно сравнивать, используя опе­рации проверки равенства (==) и проверки неравенства (!=). Обратите вни­мание, что в Java (как в С и C++) равенство обозначается двумя знаками равенства, а не одним. (Напомним, что одиночный знак равенства (=) ис­пользуется для операции присваивания.) С помощью операций упорядочи­вания (<, >, <=, >=) можно сравнивать только числовые типы (т. е., чтобы увидеть, какой операнд больше или меньше, чем другой, можно сравнивать только целочисленные, с плавающей точкой и символьные операнды).

Как было сказано ранее, результат, полученный операциями отношений, представляет собой значение типа boolean. Например, следующий кодовый фрагмент содержит совершенно правильные утверждения:

int a = 41; int b = 1; boolean с = а < b;

В этом случае результат выражения а < ь (который есть false) сохраняет­ся в с.

Если вы переходите к Java из среды C/C++, обратите внимание на следую­щее. В программах C/C++ часто встречаются следующие типы операторов:

int done;

// ...

if(!done) ... // Верно в C/C++

if(done) ... // но не в Java.

100 Часть I. Язык Java

На языке Java эти операторы должны быть записаны так:

if(done == 0)) ... // Это Java-стиль, if(done != 0) ...

Причина в том, что Java не определяет true и false таким же образом, как C/C++. В C/C++ true — любое значение, отличное от нуля, a false — нуль. В Java true и false — нечисловые значения, которые не имеют отношения к нулю или не нулю. Поэтому, чтобы выполнить проверку на равенство нулю, вы должны явно использовать одну или несколько операций отно­шений.

Операции булевой логики

Представленные в табл. 4.5 операции булевой логики работают только с опе­рандами типа boolean. Чтобы сформировать результат типа boolean, все би­нарные логические операции комбинируют два booiean-значения.

Операция Результат

& Логическое И (Logical AND) 1 Логическое ИЛИ (Logical OR) А Логическое исключающее ИЛИ (Logical XOR (exclusive OR)) Укороченное ИЛИ (Shirt-ciruit OR) && Укороченное И (Shirt-ciruit AND) ! Логическое унарное отрицание (Logical unary NOT) &= Присваивание с И (AND assignment) 1= Присваивание с ИЛИ (OR assignment) л= Присваивание с исключающим ИЛИ (XOR assignment) Равно (Equal to) != Не равно (Not equal to) ? : Троичная условная операция (Ternary if-then-else)

Действия операций булевой логики &, | и Л на булевских значениях анало­гичны их действиям на битах целых чисел. Например, логическая операция отрицания (!) инвертирует булевское значение на противоположное (itrue дает значение false, a ! false — значение true).

Табл. 4.6 показывает эффект каждой логической операции.

Соседние файлы в папке JavaLit