Приоритет операторов - 1

— Привет, Билаабо!

— Билаабо рад приветствовать друга!

Билаабо сегодня расскажет о приоритете операторов. Но сначала он расскажет о самих операторах.

— А что это такое – эти операторы?

На самом деле ты уже знаком с ними, просто, возможно, не знал, что это – операторы.

Вот, например, есть выражение c = a + b;

Тут есть два оператора: оператор сложения и оператор присваивания.

— Т.е. операторы – это просто математические знаки? Как умножение, деление и сложение?

— Ага, так и есть. Хотя есть и отличия.

Я не буду давать определение операторов: от этого ты умнее не станешь. Лучше посмотрим их на деле. Операторы можно разбить на несколько групп, и мы сейчас их рассмотрим.

1) Группа «математические операторы»

Обозначение Пример Название Описание (что делает)
+ a + b Оператор сложения Складывает два числа.
- c - d Оператор вычитания Вычитает второе число из первого.
* a * t Оператор умножения Умножает два числа.
/ a / b Оператор деления Делит первое число на второе.
% c % d Остаток от деления Вычисляет остаток от деления первого числа на второе.
- -a Одинарный минус Меняет знак переменой наобратный.
Плюс на минус, минус на плюс.
+ +a Одинарный плюс Ничего не меняет. Добавлен вместе с одинарным минусом для красоты.

— Это я и со школы знаю – мне залили школьный курс вместе с прошивкой.

А что это еще за процент такой волшебный?

— Это «остаток от деления». Если 11 делить нацело на 5, то получим 2 и остаток от деления – 1. Вот этот 1 и можно получить, если записать 11 % 5;

При делении целых чисел в Java результат тоже будет целым числом. Остаток от деления просто отбрасывается. Если разделить 8 на 5, то получим 1.

Выражение Ответ
19 / 10 1 Если делить нацело 19 на 10, получим 1 и 9 в остатке.
19 % 10 9 Если делить нацело 19 на 10, получим 1 и 9 в остатке.
2 / 5 0 Если делить нацело 2 на 5, получим 0 и 2 в остатке.
16 % 2 0 Если делить нацело 16 на 2, получим 8 и 0 в остатке.

— А зачем вообще нужен этот остаток от деления?

— Допустим тебе нужно проверить – четное число а или нет, тогда это можно записать так

if (a % 2 == 0)

А если нужно проверить, что b – нечетное, тогда это можно записать так

if (b % 2 == 1)

Или, например, делится ли d нацело на 3:

if (d % 3 == 0)

— Интересно, я это запомню.

2) Группа «операторы сравнения»

Обозначение Пример Название Описание (что делает)
< a < b Меньше Проверяет, что a меньше b.
<= c <= d Меньше или равно Проверяет, что c меньше или равно d.
> a > b Больше Проверяет, что a больше b.
>= c >= d Больше или равно Проверяет, что c больше или равно d.
== i == j Равно Проверяет, что i равно j.
!= a != 0 Неравно Проверяет, что a неравно нулю.

— Я этим всем уже пользовался.

— И какое же главное отличие этих операторов от математических операторов?

— Если мы складываем два числа, то получаем число, а если сравниваем два числа – получаем true или false.

— Верно. Результатом сравнения будет «логическое значение» или попросту одно значение из пары (true, false), которые, как ты знаешь, являются значениями типа boolean.

— Да, тут все понятно, я это уже знаю.

3) Группа «логические операторы»

Обозначение Пример Название Описание (что делает)
&& a && b AND – «и» Результат выражения true, только когда и a и b равны true.
|| c || d OR – «или» Результат выражения true, если a или b равно true. Оба или хотя бы один.
! !a NOT – «не» Результат выражения true, только если a равно false.

— Логические операторы можно применять только к переменным или выражениям логического типа.

Пример Описание
boolean a = true;
boolean b = true;if (a && b)
Условие if истинно (true), если оба значения истинны.
Т.е. если  a и b равны true, то результат – true.
boolean a = true;
boolean b = false;if (a || b)
Условие if истинно (true), если хотя бы одно значение — истина.
Т.е. если  a или b равны true, то результат – true.
boolean b = false;

if (!b)

Условие if истинно (true), если b — не истина.
Т.е. если  b равно false, то результат – true.
int a = 2, b = 3, c = 4;

if (a < b && a < c)
эквивалентно
if ((a < b) && (a < c))

Если a меньше b и a меньше c, то результат выражения – истина.
a,b,c – целые числа, но результат сравнения целых чисел – это уже логическое значение (true, false) а значит мы можем использовать логические операторы.

— Все это я и так знаю.

— Да? Тогда продолжим.

4) Группа – «побитовые операторы»

Обозначение Пример Название Описание (что делает)
& a & b AND – «и» Побитовое «И»
| c | d OR – «или» Побитовое «ИЛИ»
~ ~a NOT – «не» Побитовое «НЕ»
^ a ^ b XOR – «исключающее или» Побитовое «ИСКЛЮЧАЮЩЕЕ ИЛИ»

— Побитовые операторы выполняю операцию над целыми числами побитово.

— Это как?

— Каждое число представляется в виде набора бит, а затем вычисляется результат по такой схеме:

Если первый бит в обоих числах равен 1, то первый бит результата будет 1.

Если второй бит в обоих числах равен 1, то второй бит результата будет 1. И так далее

— Это верно для всех побитовых операторов?

— Тут все намного проще. Бит может принимать только два значения – 0 и 1, так?

— Да.

— Тогда представь, что 1 – это true, а 0 – это false. Тогда операции над отдельными битами будут практически такими же, как и логические операции:

Логическое выражение Битовое выражение
true && true == true 1&1 == 1
true && false == false 1&0 == 0
true || true == true 1|1 == 1
true || false == true 1|0 == 1
false || false = false 0|0 == 0
!false == true ~0 == 1
!true == false ~1 == 0

— О! Так все же очень просто.

— Да, только не забывай, что в побитовых операциях участвуют биты двух чисел, которые расположены на одних и тех же местах.

— Да, я помню: первый бит одного числа взаимодействует с первым битом второго, и результат записывается также в первый бит. Для остальных битов – аналогично.

— Верно. Есть еще вопросы?

— А что это за XOR еще такой – «исключающее или»?

— Тут тоже все просто: когда значение разные – истина (true, 1), когда одинаковые – (false, 0)

Логическое выражение Битовое выражение
true XOR true == false 1 ^ 1 == 0
false XOR false == false 0 ^ 0 == 0
true XOR false == true 1 ^ 0 == 1
false XOR true == true 0 ^ 1 == 1

Вот тебе еще пара примеров побитовых операций:

Пример Числа в битовом виде Ответ в битовом виде Ответ
5 & 3 00000101 & 00000011 00000001 1
7 & 2 00000111 & 00000010 00000010 2
5 | 9 00000101 | 00001001 00001101 13
5 ^ 9 00000101 ^ 00001001 00001100 12
~9 ~00001001 11110110 246

— Спасибо, Билаабо. Буду знать.

— Есть еще одна группа побитовых операторов – операторы сдвига:

5) Группа «операторы сдвига»

Обозначение Пример Название Описание (что делает)
>> a >> b сдвиг вправо Сдвигает биты числа a, на b разрядов вправо.
<< c << d сдвиг влево Сдвигает биты числа c, на d разрядов влево.
>>> a >>> 2 сдвиг вправо с заполнением нулем Сдвигает биты числа a, на 2 разряда вправо.

— Это что еще за уличная магия?

— На самом деле тут все просто. Вот смотри:

Пример Числа в битовом виде Ответ в битовом виде Ответ
10 >> 1 00001010 >> 1 00000101 5
10 >> 2 00001010 >> 2 00000010 2
10 << 1 00001010 << 1 00010100 20
10 << 2 00001010 << 2 00101000 40

Сдвига разрядов числа на 1 влево – то же самое, что умножить число на 2. На два разряда равно умножению на 4, на три разряда – умножению на 8 и так далее.

Сдвиг вправо – соответственно, деление на 2,4,8,16,… и так далее.

— А в чем отличие операторов «>>>» и «>>»?

— Они отличаются при работе с отрицательными числами. Дело в том, что знак отрицательного числа хранится в крайнем левом бите. И при сдвиге вправо число перестает быть отрицательным. Поэтому и придумали два различных оператора, вот смотри:

Выражение Результат Описание
10001010 >> 1 11000101 Отрицательное число остается отрицательным.
Новые разряды заполняются 1, для отрицательных чисел.
10001010 >> 2 11100010
10001010 >> 3 11110001
10001010 >>> 1 01000101 Отрицательное число перестает быть отрицательным. Новые разряды заполняются 0, для отрицательных чисел.
10001010 >>> 2 00100010
10001010 >>> 3 00010001

Сдвиг не циклический. Биты, которые оказались за краем числа слева или справа, просто отбрасываются.

6) Группа «операторы присваивания»

— Присваивание я уже знаю. А почему ты говоришь операторы?

— Потому что их несколько ☺

Оператор Что он значит
a += b; a = a + b;
a -= b; a = a - b;
a *= b; a = a * b;
a %= b; a = a % b;
a |= b; a = a | b;
a &= b; a = a & b;

Думаю, логика тебе ясна.

7) Группа «операторы инкремента и декремента»

Запись Пример Описание
++ a++;
++b;
Увеличивает число на 1.
-- d--;
--i;
Уменьшает число/переменную на 1.

— А в чем отличие, когда два минуса спереди или сзади?

— А отличие есть. Хоть и не очень большое. Если переменная с таким оператором участвует в каком-нибудь выражении или присваивании, то тут возникают различия. Давай я лучше покажу тебе на примере:

Пример Что происходит на самом деле Описание
int a = 3;
int b = ++a;
int a = 3;
a = a + 1;
int b = a;
а сначала увеличивается на 1, затем участвует в выражении.
int a = 3;
int b = a++;
int a = 3;
int b = a;
a = a + 1;
а сначала участвует в выражении, затем увеличивается на 1.
int a = 3;
return a++;
int a = 3;
int result = a;
a = a + 1;
return result;
функция вернет 3, но значение a будет увеличено на 1.
int x = 5;
x = ++x + ++x;
int x = 5;
int a = x + 1;//первое слагаемое 6
x = a;
int b = x + 1;//второе слагаемое 7
x = b;
x = a + b;
тут будет ответ 13. Сначала x увеличится на 1, и это значение подставится на место первого слагаемого, а потом х увеличится еще раз на 1.

— Ничего себе! Вот это круто!

— Рад, что тебе понравилось. Но, если нет никакого выражения или присваивания, то никаких отличий нет:

Просто «x++» эквивалентно x = x + 1.

Просто «++x» тоже эквивалентно x = x + 1.

— Буду знать, спасибо, Билаабо.

8) Группа «тернарный оператор»

— В этом операторе участвуют не одна переменная/выражение и не две, а сразу три:

Вот как он записывается А вот чему он эквивалентен:
a ? b : c; if (a)
b
else
c
int min = a < b ? a : b; if (a < b)
min = a;
else
min = b;
return a != null ? a.length : 0; if (a != null)
return a.length;
else
return 0;

— Так это же очень удобная штука.

— Ага. И компактно и код читабельный. Пользуйся на здоровье.

9) Группа «остальное»

— Сколько музыку ни разбирай, а папку «разное» создать придется.

— Да, каждый, кто хоть раз это делал, полностью с тобой согласен.

— Так вот, есть еще три оператора, о которых я хотел тебе рассказать:

Запись Пример Описание
() (a + b) * c Скобки повышают приоритет выполнения.
Сначала выполняется то, что в скобках.
[] c [i] = c [i + 1]; Получение элемента массива по индексу.
. int n = a.length; «оператор точка» – получение переменных и методов у объекта.

И, наконец, приоритет операторов и порядок их выполнения:

Операторы Примеры
Высший приоритет (сначала выполняются операторы расположенные выше в таблице)
()
[]
.
(a + b)
c [i] = c [i] + 1
++
--
~
!
+
-
i++; ++i;
--j; a--;
~c
!f
return +a;
return -a;
*
/
%
a * b
c / d
a % b
+
-
a + b
c - d
String s = "count"+"35 ";
>>
<<
>>>
a >> 3
b << 2
c >>> 3
<
<=
>
>=
a < b
a <= b
c > b
c >= b
==
!=
a == 3
a != 0
& a & 7
^ a ^ b
| a | b
&& (a < b) && (a < c)
|| (b != 0) || (c != 0)
? : = a > 0 ? a : -a;
=
*=, /=, %=
-=, +=
<<=. >>=, >>>=
&=, ^=. |=
Низший приоритет (выполняются в самом конце)