
— Привет, Билаабо!
— Билаабо рад приветствовать друга!
Билаабо сегодня расскажет о приоритете операторов. Но сначала он расскажет о самих операторах.
— А что это такое – эти операторы?
На самом деле ты уже знаком с ними, просто, возможно, не знал, что это – операторы.
Вот, например, есть выражение 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 истинно (true), если b — не истина. Т.е. если b равно false, то результат – true. |
int a = 2, b = 3, c = 4;
|
Если 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; |
= *=, /=, %= -=, += <<=. >>=, >>>= &=, ^=. |= |
|
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ