0 added
0 removed
Original
2026-01-01
Modified
2026-02-21
1
<p><a>#База знаний</a></p>
1
<p><a>#База знаний</a></p>
2
<ul><li>11 мар 2021</li>
2
<ul><li>11 мар 2021</li>
3
<li>0</li>
3
<li>0</li>
4
</ul><p>Что за операторы такие, зачем им префиксная и постфиксная формы, и как вычислять сложные выражения с ними (пригодится на экзамене и собеседовании).</p>
4
</ul><p>Что за операторы такие, зачем им префиксная и постфиксная формы, и как вычислять сложные выражения с ними (пригодится на экзамене и собеседовании).</p>
5
<p>Программист, преподаватель Skillbox. Пишет про Java. </p>
5
<p>Программист, преподаватель Skillbox. Пишет про Java. </p>
6
<p>В программировании часто приходится выполнять операции (вычислять результат выражений), в которых переменная должна увеличиться или уменьшиться на единицу.</p>
6
<p>В программировании часто приходится выполнять операции (вычислять результат выражений), в которых переменная должна увеличиться или уменьшиться на единицу.</p>
7
<p>Для этого придуманы унарные операторы ++ и --. С ними код короче и писать его быстрее.</p>
7
<p>Для этого придуманы унарные операторы ++ и --. С ними код короче и писать его быстрее.</p>
8
<p>Оператор (++) называется инкремент. Он увеличивает значение целочисленной переменной на единицу.</p>
8
<p>Оператор (++) называется инкремент. Он увеличивает значение целочисленной переменной на единицу.</p>
9
<p>Обратный оператор (--) зовётся декремент. Он значение переменной на один уменьшает.</p>
9
<p>Обратный оператор (--) зовётся декремент. Он значение переменной на один уменьшает.</p>
10
int x = 3, у = 3; x++; // инкрементируем x у--; // декрементируем y System.out.println("x = " + x + ", y = " + y); --OUTPUT> x = 4, y = 2<p>Тут всё просто, достаточно удостовериться, что значения переменных поменялись.</p>
10
int x = 3, у = 3; x++; // инкрементируем x у--; // декрементируем y System.out.println("x = " + x + ", y = " + y); --OUTPUT> x = 4, y = 2<p>Тут всё просто, достаточно удостовериться, что значения переменных поменялись.</p>
11
<p><strong>Примечание.</strong>Инкремент и декремент относятся к арифметическим операторам. Мы помним, что операнды арифметических операторов должны быть числового типа. Однако в Java допустим и тип char, потому что здесь это по сути разновидность типа int.</p>
11
<p><strong>Примечание.</strong>Инкремент и декремент относятся к арифметическим операторам. Мы помним, что операнды арифметических операторов должны быть числового типа. Однако в Java допустим и тип char, потому что здесь это по сути разновидность типа int.</p>
12
<p>Проверим, как это работает с инкрементом и декрементом.</p>
12
<p>Проверим, как это работает с инкрементом и декрементом.</p>
13
char x = 'b', y = 'c'; x++; // инкрементируем x y--; // декрементируем y System.out.println("x = " + x); System.out.println("y = " + y); --OUTPUT> x = c y = b<p>Работает: инкремент помещает в символьную переменную следующий знак из кодировки ASCII, а декремент - предыдущий.</p>
13
char x = 'b', y = 'c'; x++; // инкрементируем x y--; // декрементируем y System.out.println("x = " + x); System.out.println("y = " + y); --OUTPUT> x = c y = b<p>Работает: инкремент помещает в символьную переменную следующий знак из кодировки ASCII, а декремент - предыдущий.</p>
14
for (int i = 0; i < 3; i++) { System.out.println(i); } --OUTPUT> 0 1 2<p>На каждой итерации цикла значение переменной i выводится в консоль, а сама переменная увеличивается на один после каждого витка.</p>
14
for (int i = 0; i < 3; i++) { System.out.println(i); } --OUTPUT> 0 1 2<p>На каждой итерации цикла значение переменной i выводится в консоль, а сама переменная увеличивается на один после каждого витка.</p>
15
<p><strong>Примечание:</strong>если в примере выше заменить i++ на ++i, то результат в консоли не поменяется - проверьте.</p>
15
<p><strong>Примечание:</strong>если в примере выше заменить i++ на ++i, то результат в консоли не поменяется - проверьте.</p>
16
<p>Почему?</p>
16
<p>Почему?</p>
17
<p>Дело в том, что преинкремент и постинкремент в условии цикла for можно сравнить с вызовом двух разных функций. Каждая из них делает одно и то же - увеличивает переменную i (после выполнения тела цикла), и только возвращаемые ими значения различаются.</p>
17
<p>Дело в том, что преинкремент и постинкремент в условии цикла for можно сравнить с вызовом двух разных функций. Каждая из них делает одно и то же - увеличивает переменную i (после выполнения тела цикла), и только возвращаемые ими значения различаются.</p>
18
<p>Однако возвращаемое инкрементом значение в условии цикла использовать негде (нет выражения для вычисления) - поэтому оно просто выбрасывается.</p>
18
<p>Однако возвращаемое инкрементом значение в условии цикла использовать негде (нет выражения для вычисления) - поэтому оно просто выбрасывается.</p>
19
<p>Вот почему на работе цикла подобная замена не отразилась.</p>
19
<p>Вот почему на работе цикла подобная замена не отразилась.</p>
20
<p>Перепишем пример с циклом так:</p>
20
<p>Перепишем пример с циклом так:</p>
21
for (int i = 0; i < 3;) { System.out.println(i++); } --OUTPUT> 0 1 2<p>Как видим, вывод снова не изменился.</p>
21
for (int i = 0; i < 3;) { System.out.println(i++); } --OUTPUT> 0 1 2<p>Как видим, вывод снова не изменился.</p>
22
<p>Всё потому, что в метод System.<em>out</em>.println () передаётся текущее значение переменной i, и лишь потом оно увеличивается на единицу.</p>
22
<p>Всё потому, что в метод System.<em>out</em>.println () передаётся текущее значение переменной i, и лишь потом оно увеличивается на единицу.</p>
23
<p>За это отвечает постфиксная форма записи инкремента. А ещё есть префиксная. И для декремента тоже.</p>
23
<p>За это отвечает постфиксная форма записи инкремента. А ещё есть префиксная. И для декремента тоже.</p>
24
<p>Синтаксис тут такой (x - переменная):</p>
24
<p>Синтаксис тут такой (x - переменная):</p>
25
<strong>Операция</strong><strong>Постфиксная версия</strong><strong>Префиксная версия</strong>Инкремент x++ ++x Декремент х-- --х<ul><li>Префиксные операторы ++x (--x) записывают в переменную x изменённое значение и его же возвращают вместо себя (в исходное выражение).</li>
25
<strong>Операция</strong><strong>Постфиксная версия</strong><strong>Префиксная версия</strong>Инкремент x++ ++x Декремент х-- --х<ul><li>Префиксные операторы ++x (--x) записывают в переменную x изменённое значение и его же возвращают вместо себя (в исходное выражение).</li>
26
<li>Постфиксные операторы x++ (x--) возвращают вместо себя текущее значение переменной х, а потом записывают в x новое значение.</li>
26
<li>Постфиксные операторы x++ (x--) возвращают вместо себя текущее значение переменной х, а потом записывают в x новое значение.</li>
27
</ul><p>Обратите внимание на слово<strong>потом</strong>. Потом - это когда? После вычисления всего выражения? Чтобы понять это, разберёмся с порядком вычисления инкрементов и декрементов.</p>
27
</ul><p>Обратите внимание на слово<strong>потом</strong>. Потом - это когда? После вычисления всего выражения? Чтобы понять это, разберёмся с порядком вычисления инкрементов и декрементов.</p>
28
<p>Значения, которые инкременты возвращают в выражение, вычисляются до выполнения других операций. И то же самое для декрементов.</p>
28
<p>Значения, которые инкременты возвращают в выражение, вычисляются до выполнения других операций. И то же самое для декрементов.</p>
29
<p>То есть у операторов ++ и -- наивысший приоритет при вычислении результата выражения.</p>
29
<p>То есть у операторов ++ и -- наивысший приоритет при вычислении результата выражения.</p>
30
<p>Не путайте<em>приоритет</em>с обычным порядком выполнения операторов. Все инструкции Java выполняет в привычном нам направлении (слева направо), и операнды операторов вычисляет так же.</p>
30
<p>Не путайте<em>приоритет</em>с обычным порядком выполнения операторов. Все инструкции Java выполняет в привычном нам направлении (слева направо), и операнды операторов вычисляет так же.</p>
31
<p>Все арифметические операторы (за исключением унарных + и -; преинкремента ++x и предекремента --x) -<em>левоассоциативны</em>, то есть выполняются слева направо.</p>
31
<p>Все арифметические операторы (за исключением унарных + и -; преинкремента ++x и предекремента --x) -<em>левоассоциативны</em>, то есть выполняются слева направо.</p>
32
<p><em>Приоритеты</em>же определяют порядок выполнения операторов, которые сами являются частью более сложного (составного) арифметического или логического выражения.</p>
32
<p><em>Приоритеты</em>же определяют порядок выполнения операторов, которые сами являются частью более сложного (составного) арифметического или логического выражения.</p>
33
<p>Если на одном уровне встречаются операции одинакового<em>приоритета</em>, то какие из них выполнять первыми - определяет уже<em>ассоциативность</em>.</p>
33
<p>Если на одном уровне встречаются операции одинакового<em>приоритета</em>, то какие из них выполнять первыми - определяет уже<em>ассоциативность</em>.</p>
34
int x = 3; int y = 3; int a = 2 * x++; // здесь значение a равно 6, а x равен 4 int b = 2 * --y; // здесь значение b равно 4, а y равен 2 System.out.println(a); System.out.println(b); System.out.println(x); System.out.println(y); --OUTPUT> 6 4 4 2<p>Разберём пример выше.</p>
34
int x = 3; int y = 3; int a = 2 * x++; // здесь значение a равно 6, а x равен 4 int b = 2 * --y; // здесь значение b равно 4, а y равен 2 System.out.println(a); System.out.println(b); System.out.println(x); System.out.println(y); --OUTPUT> 6 4 4 2<p>Разберём пример выше.</p>
35
<p><strong>x = 3.</strong>Найдём значение выражения 2 * x++:</p>
35
<p><strong>x = 3.</strong>Найдём значение выражения 2 * x++:</p>
36
<ul><li>Сперва вычисляем постинкремент x++, он возвращает в выражение текущее значение x, то есть 3, а потом увеличивает x на 1.</li>
36
<ul><li>Сперва вычисляем постинкремент x++, он возвращает в выражение текущее значение x, то есть 3, а потом увеличивает x на 1.</li>
37
<li>Это эквивалентно исполнению кода: a = 2 * x; x = x + 1;</li>
37
<li>Это эквивалентно исполнению кода: a = 2 * x; x = x + 1;</li>
38
<li>Значение a стало равняться 6, а x равен 4.</li>
38
<li>Значение a стало равняться 6, а x равен 4.</li>
39
</ul><p><strong>y = 3.</strong>Вычислим значение выражения 2 * --y:</p>
39
</ul><p><strong>y = 3.</strong>Вычислим значение выражения 2 * --y:</p>
40
<ul><li>Сперва вычисляем предекремент --y, он уменьшает y на 1 и возвращает вместо себя это новое значение.</li>
40
<ul><li>Сперва вычисляем предекремент --y, он уменьшает y на 1 и возвращает вместо себя это новое значение.</li>
41
<li>Это эквивалентно исполнению кода: y = y - 1; b = 2 * y;</li>
41
<li>Это эквивалентно исполнению кода: y = y - 1; b = 2 * y;</li>
42
</ul><p>Значение b стало равным 4, а y равен 2.</p>
42
</ul><p>Значение b стало равным 4, а y равен 2.</p>
43
<p>Если декременты или инкременты разделены каким-нибудь бинарным оператором (вроде +, -, *, /), то ассоциативностью они уже не связаны (так как приоритет бинарного оператора заведомо ниже). И тогда мы вычисляем значение выражения традиционным методом - слева направо, учитывая приоритет операций Java.</p>
43
<p>Если декременты или инкременты разделены каким-нибудь бинарным оператором (вроде +, -, *, /), то ассоциативностью они уже не связаны (так как приоритет бинарного оператора заведомо ниже). И тогда мы вычисляем значение выражения традиционным методом - слева направо, учитывая приоритет операций Java.</p>
44
<p>В этом случае стоит помнить, что:</p>
44
<p>В этом случае стоит помнить, что:</p>
45
<ul><li>раньше всегда вычисляется декремент или инкремент, который стоит левее;</li>
45
<ul><li>раньше всегда вычисляется декремент или инкремент, который стоит левее;</li>
46
<li>скобки на порядок вычисления инкрементов и декрементов не влияют;</li>
46
<li>скобки на порядок вычисления инкрементов и декрементов не влияют;</li>
47
<li>конструкции типа ++x-- (--x++, ++x++ или --x--) запрещены.</li>
47
<li>конструкции типа ++x-- (--x++, ++x++ или --x--) запрещены.</li>
48
</ul><p><strong>Если в выражении много инкрементов/декрементов одной переменной</strong></p>
48
</ul><p><strong>Если в выражении много инкрементов/декрементов одной переменной</strong></p>
49
<p>Тогда входным значением переменной для вычисления каждого последующего инкремента или декремента будет значение этой переменной после вычисления предыдущего инкремента или декремента.</p>
49
<p>Тогда входным значением переменной для вычисления каждого последующего инкремента или декремента будет значение этой переменной после вычисления предыдущего инкремента или декремента.</p>
50
<p>То есть инкременты/декременты в выражении обрабатываются не одновременно, а по очереди, порядок в которой определяется ассоциативностью и приоритетом этих операторов в Java.</p>
50
<p>То есть инкременты/декременты в выражении обрабатываются не одновременно, а по очереди, порядок в которой определяется ассоциативностью и приоритетом этих операторов в Java.</p>
51
<p>Рассмотрим это на примере.</p>
51
<p>Рассмотрим это на примере.</p>
52
int x = 5; int y = ++x + x--; System.out.println("x = " + x); System.out.println("y = " + y); --OUTPUT> 5 12<p><strong>Как думаете, почему значения такие?</strong></p>
52
int x = 5; int y = ++x + x--; System.out.println("x = " + x); System.out.println("y = " + y); --OUTPUT> 5 12<p><strong>Как думаете, почему значения такие?</strong></p>
53
<p>Разберём пример выше.</p>
53
<p>Разберём пример выше.</p>
54
<p><strong>x = 5.</strong>Начинаем вычислять выражение ++x + x--:</p>
54
<p><strong>x = 5.</strong>Начинаем вычислять выражение ++x + x--:</p>
55
<ul><li>Двигаемся слева направо до первого инкремента/декремента. У нас это ++x (преинкремент x). Мы помним, что он увеличивает x на 1 и сразу возвращает вместо себя это новое значение x (5 + 1 = 6).</li>
55
<ul><li>Двигаемся слева направо до первого инкремента/декремента. У нас это ++x (преинкремент x). Мы помним, что он увеличивает x на 1 и сразу возвращает вместо себя это новое значение x (5 + 1 = 6).</li>
56
<li>Подставляем 6 в наше выражение вместо ++x: y = 6 + x--.</li>
56
<li>Подставляем 6 в наше выражение вместо ++x: y = 6 + x--.</li>
57
<li>Вновь двигаемся слева направо до первого инкремента/декремента.</li>
57
<li>Вновь двигаемся слева направо до первого инкремента/декремента.</li>
58
<li>Встречаем x-- (постдекремент x). Вспоминаем, что он возвращает вместо себя текущее значение x (которое у нас после инкремента равно 6).</li>
58
<li>Встречаем x-- (постдекремент x). Вспоминаем, что он возвращает вместо себя текущее значение x (которое у нас после инкремента равно 6).</li>
59
<li>Подставляем 6 в вычисляемое выражение вместо x--. Получаем: y = 6 + 6.</li>
59
<li>Подставляем 6 в вычисляемое выражение вместо x--. Получаем: y = 6 + 6.</li>
60
<li>Вспоминаем, что не до конца исполнили постдекремент x, осталось уменьшить x на 1. Теперь значение x будет равно 6 - 1. То есть 5.</li>
60
<li>Вспоминаем, что не до конца исполнили постдекремент x, осталось уменьшить x на 1. Теперь значение x будет равно 6 - 1. То есть 5.</li>
61
</ul><p>Вот мы и поработали процессорами (получили вручную те же самые значения):</p>
61
</ul><p>Вот мы и поработали процессорами (получили вручную те же самые значения):</p>
62
<p>х = 5; y = 12.</p>
62
<p>х = 5; y = 12.</p>
63
<p>А теперь пример посложнее (такие дают на экзаменах и собеседованиях).</p>
63
<p>А теперь пример посложнее (такие дают на экзаменах и собеседованиях).</p>
64
int x = 4; int y = ++x * 3 / x-- + --x; System.out.println("x = " + x); System.out.println("y = " + y);<p>Принципиально этот пример не отличается от предыдущего. Только будьте аккуратны при вычислениях. Потому что на этот раз инкременты и декременты меняют значение x трижды в одном выражении.</p>
64
int x = 4; int y = ++x * 3 / x-- + --x; System.out.println("x = " + x); System.out.println("y = " + y);<p>Принципиально этот пример не отличается от предыдущего. Только будьте аккуратны при вычислениях. Потому что на этот раз инкременты и декременты меняют значение x трижды в одном выражении.</p>
65
<p><strong>x = 4.</strong>Вычислим значение выражения ++x * 3 / x-- + --x.</p>
65
<p><strong>x = 4.</strong>Вычислим значение выражения ++x * 3 / x-- + --x.</p>
66
<p>Действуем как и раньше:</p>
66
<p>Действуем как и раньше:</p>
67
<ul><li>Двигаемся слева направо до первого инкремента/декремента. Встречаем ++x (преинкремент x).<p>Как помним, он увеличивает</p>
67
<ul><li>Двигаемся слева направо до первого инкремента/декремента. Встречаем ++x (преинкремент x).<p>Как помним, он увеличивает</p>
68
x на 1 и сразу возвращает вместо себя новое значение x (4 + 1 = 5).<p>Подставляем 5 в наше выражение вместо</p>
68
x на 1 и сразу возвращает вместо себя новое значение x (4 + 1 = 5).<p>Подставляем 5 в наше выражение вместо</p>
69
++x: 5 * 3 / x-- + --x.</li>
69
++x: 5 * 3 / x-- + --x.</li>
70
<li>Идём слева направо до первого инкремента/декремента. Встречаем x-- (постдекремент x), заменяем его текущим значением x. Переписываем наше выражение: 5 * 3 / 5 + --x.<p>Вспоминаем, что не до конца исполнили постдекремент</p>
70
<li>Идём слева направо до первого инкремента/декремента. Встречаем x-- (постдекремент x), заменяем его текущим значением x. Переписываем наше выражение: 5 * 3 / 5 + --x.<p>Вспоминаем, что не до конца исполнили постдекремент</p>
71
x, осталось уменьшить x на 1. Теперь значение x станет равно 5 - 1. То есть 4.</li>
71
x, осталось уменьшить x на 1. Теперь значение x станет равно 5 - 1. То есть 4.</li>
72
<li>Вновь двигаемся слева направо до первого инкремента/декремента: 5 * 3 / 5 + --x.<p>Встречаем</p>
72
<li>Вновь двигаемся слева направо до первого инкремента/декремента: 5 * 3 / 5 + --x.<p>Встречаем</p>
73
--x (предекремент x), он уменьшает x на 1 и сразу возвращает вместо себя новое значение x (4 - 1 = 3).<p>Подставляем 3 в наше выражение вместо</p>
73
--x (предекремент x), он уменьшает x на 1 и сразу возвращает вместо себя новое значение x (4 - 1 = 3).<p>Подставляем 3 в наше выражение вместо</p>
74
--x: y = 5 * 3 / 5 + 3.</li>
74
--x: y = 5 * 3 / 5 + 3.</li>
75
<li>Вспоминаем приоритет арифметических операций в Java - и вычисляем значение y.</li>
75
<li>Вспоминаем приоритет арифметических операций в Java - и вычисляем значение y.</li>
76
</ul><p>Узнаём, что y = 6, а x = 3.</p>
76
</ul><p>Узнаём, что y = 6, а x = 3.</p>
77
<p>Запустим код и сверимся с результатом в консоли:</p>
77
<p>Запустим код и сверимся с результатом в консоли:</p>
78
int x = 4; int y = ++x * 3 / x-- + --x; System.out.println("x = " + x); System.out.println("y = " + y); --OUTPUT> x = 3 y = 6<p>Совпало, ура!</p>
78
int x = 4; int y = ++x * 3 / x-- + --x; System.out.println("x = " + x); System.out.println("y = " + y); --OUTPUT> x = 3 y = 6<p>Совпало, ура!</p>
79
<p>Мы познакомились с инкрементом и декрементом, с их префиксной и постфиксной формами в Java, научились вычислять сложные выражения с ними.</p>
79
<p>Мы познакомились с инкрементом и декрементом, с их префиксной и постфиксной формами в Java, научились вычислять сложные выражения с ними.</p>
80
<p>Советуем сразу же потренироваться. Проверить себя можно в любом онлайн-компиляторе Java (даже со смартфона). Удачи на экзамене и собеседовании!</p>
80
<p>Советуем сразу же потренироваться. Проверить себя можно в любом онлайн-компиляторе Java (даже со смартфона). Удачи на экзамене и собеседовании!</p>
81
<a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>
81
<a><b>Бесплатный курс по Python ➞</b>Мини-курс для новичков и для опытных кодеров. 4 крутых проекта в портфолио, живое общение со спикером. Кликните и узнайте, чему можно научиться на курсе. Смотреть программу</a>