Что это такое? Инкремент и декремент – операции, использующиеся в языках программирования для ускорения работы процессов. По сути, это увеличение/уменьшение значения переменной на 1.
На что обратить внимание? Несмотря на кажущуюся простоту применения данных инструментов, существуют ситуации, где их использование, наоборот, вносит путаницу в код и вычисления.
В статье рассказывается:
- Что такое инкремент и декремент
- Инкремент и декремент в программировании
- Примеры с инкрементом и декрементом в Java
- Реализация инкрементов и декрементов в других языках программирования
- Рекомендации по использованию инкрементов и декрементов
- Проблемы инкремента и декремента
-
Пройди тест и узнай, какая сфера тебе подходит:
айти, дизайн или маркетинг.Бесплатно от Geekbrains
Что такое инкремент и декремент
Прежде чем рассмотреть понятия «инкремент» и «декремент», а также разницу между ними, обозначим другие базовые термины программирования.
Операнды — объекты, над которыми или при помощи которых выполняются операции, задаваемые инструкциями (операторами).
Оператор — это команда, обозначающая определённое математическое или логическое действие, выполняемое операндами. Рассмотрим на самом простом примере: 2+2. Числа в данном выражении являются операндами, а знак сложения — оператором. Инкремент и декремент относятся к арифметическим унарным командам.
Оператор, обозначаемый «++», называется инкрементом. Он увеличивает значение переменной на 1. Декремент — это обратный элемент, который уменьшает значение переменной на 1. В программном коде он обозначается «—». Это главное, чем отличается декремент от инкремента.
Они относятся к унарным математическим операциям. Это действия над одним операндом, возвращающие один результат. Проще говоря, они имеют единственный вход и выход.
Инкремент и декремент в программировании
Арифметические операции инкремент и декремент используются во многих языках программирования. Это Java, C, C++, C#, а также машинный язык большинства микропроцессоров. В качестве примера их применения можно привести цикл, в котором блок кода становится больше или меньше на единицу в каждом новом шаге.
В ряде языков программирования есть возможность инкремента не только чисел, но и типа данных bool. Например, в C++. Но применить декремент к bool нельзя. Компилятор выдаст сообщение об ошибке.
Поскольку операции инкремента и декремента используются в большинстве проектов, арифметическое устройство процессора может выполнять их на аппаратном уровне. Для осуществления этой задачи есть низкоуровневая команда. В связи с этим данные процессы выполняются гораздо быстрее, нежели прибавление или вычитание единицы обычным способом.
Эти арифметические операторы являются унарными и изменяют свои операнды. Именно поэтому перегрузку инкремента и декремента лучше всего осуществлять как функцию-член, а не как свободную.
входят в ТОП-30 с доходом
от 210 000 ₽/мес
Скачивайте и используйте уже сегодня:
Топ-30 самых востребованных и высокооплачиваемых профессий 2023
Поможет разобраться в актуальной ситуации на рынке труда
Подборка 50+ бесплатных нейросетей для упрощения работы и увеличения заработка
Только проверенные нейросети с доступом из России и свободным использованием
ТОП-100 площадок для поиска работы от GeekBrains
Список проверенных ресурсов реальных вакансий с доходом от 210 000 ₽
Большинство компиляторов кода на языке С автоматически ставят инкремент вместо выражения вида «х = x + 1» и «x += 1». Это облегчает работу программисту.
Примеры с инкрементом и декрементом в Java
Рассмотрим пример:
1 int x = 10, z = 10;
2 x++;
3z—;
4
5 System.out.println(«x: » + x + «, z: » + z);
В итоге x будет инкрементирована, а z — декрементирована. В терминале отобразится: x: 11, z: 9.
На самом деле возможно следующее написание:
1 int x = 10, z = 10;
2 x = x + 1;
3 z = z — 1;
4
5 System.out.println(«x: » + x + «, z: » + z);
Читайте также!
Возникает риторический вопрос: какой смысл в написании лишнего, если стоит достаточно простая задача — увеличить или уменьшить переменную на 1?
Мы рассмотрели, какие процессы выполняют инкременты и декременты, а также отличия между ними. Важно разобраться в формах этих арифметических операторов. Их всего 2: префиксная и постфиксная.
Скачать файлЭто достаточно просто. В префиксной (Prefix) форме плюсы или минусы ставятся перед названием переменной в формате «++x» или «—x» и изначально инкрементируют или декрементируют ее.
В постфиксной (Postfix) форме обозначения располагаются после названия переменной в формате «x++» или «x—» и инкрементируют или декрементируют ее после вычисления.
Обратите внимание на то, что используется слово вычисление в контексте определения. Это важно, так как инкремент и декремент префиксный и постфиксный работают одинаково в случае, если нет данного процесса. Пример без вычисления:
1 int x = 10, z = 10;
2 x++;
3 ++z;
4
5 System.out.println(«x: » + x + «, z: » + z);
Итак, обе переменные будут равны 11.
Пример с вычислением:
1 Int x = 10, c = 10;
2 final int y = 13 — x++;
3 final int z = 13 — ++c;
4
5 System.out.println(«y: » + y + «, z: » + z);
на обучение «Разработчик» до 24 ноября
Таким образом, в результате переменные «x» и «c» одинаковы. Уравнения в выражении схожи, но применяются разные формы записи инкремента. После вычислений переменная «y» будет 3, а переменная «z» будет 2. Внимательный читатель уже понял, с чем это связано. Постфиксная форма сработает после вычислений. Уравнение будет выглядеть следующим образом:
1 x = 10;
2
3 // Начало уравнения.
4 y = 13 — x; // Первым делом осуществляем вычисление («x» все еще 10).
5 x += 1; // Увеличиваем на 1.
6 // Конец уравнения.
Префиксная форма сработает следующим образом:
1 c = 10;
2
3 // Начало уравнения.
4 c += 1; // Увеличиваем на 1
5 z = 13 — c; // Осуществляем вычисление («c» уже 11)
6 // Конец уравнения.
Вот и основные тонкости префиксного и постфиксного инкремента и декремента.
Реализация инкрементов и декрементов в других языках программирования
Операция увеличения или уменьшения на единицу используется в языках программирования, которые наследуют C и C++. Это Java, JavaScript, PHP и другие. Применяется она с циклом for. Во многих языках программирования параметры этого цикла с предусловием выглядят как (int i = 0; i <10; i++). Использовать инкремент удобно для увеличения значения.
У языка программирования Рython отсутствует инкремент и декремент, так как циклы задаются посредством iterable-объектов. В основном их получают функцией range()), i++ тут абсолютно ни к чему.
Инкремент и декремент в С++ | |||
Операция | Обозначение | Пример | Характеристика |
преинкремент | ++ | cout << ++value; | Значение в переменной value увеличивается. Далее оператор cout выводит его в консоль. |
предекремент | — | cout << —value; | Значение в переменной value уменьшается. Далее оператор cout выводит его в консоль. |
постинкремент | ++ | cout << value++; | Оператор cout сначала выводит значение переменной value, после чего увеличивает его на 1. |
постдекремент | — | cout << value—; | Оператор cout сначала выводит значение переменной value, после чего уменьшает его на 1. |
В примерах, приведённых в таблице, используется оператор cout для демонстрации различий схем действия инкремента и декремента постфиксного и префиксного. Вместо него возможно использование многих других операторов. Это зависит от того, какую задачу решает разработчик.
Рекомендации по использованию инкрементов и декрементов
Данные операторы не относятся к числу сложных. Однако встречаются случаи, когда даже разработчики с большим практическим опытом неправильно применяют операции инкремента и декремента. Расскажем, соблюдение каких правил поможет специалистам в их работе. В особенности это актуально для начинающих программистов.
- Применяйте инкремент и декремент в си, js и других языках программирования, только если отсутствует принципиальная разница в использовании префиксной или постфиксной формы.
- Не используйте в рамках одного выражения операции, не несущие побочные эффекты с теми процессами, у которых они есть.
- Не применяйте в одном программном коде несколько операций данного типа, делая из него длинную цепочку «вагонов».
- Помните, что первым делом вычисляется инкремент или декремент, находящийся в левой части выражения.
- Нет смысла брать выражения с данными операторами в скобки, так как это не отражается на порядке вычисления и не дает приоритетность.
Побочный эффект — это действия, оказываемые выражением и изменяющие среду выполнения.
Обратите внимание на приоритетность при вычислении результата. У операторов инкремента и декремента в С, С++ и других языках программирования она есть. Однако не нужно путать данное понятие с принятым стандартным порядком выполнения операций в языках программирования. В Java он слева направо. В данной последовательности вычисляются операнды операторов. Это относится и к арифметическим командам, за исключением преинкремента и предекремента («++x» и «—x»).
Приоритеты влияют на порядок выполнения операторов в многоуровневой структуре выражений. В случае если на одном уровне располагаются операции с одинаковым приоритетом, то они вычисляются по правилу ассоциативности. Программист обязательно должен учитывать эти особенности.
Проблемы инкремента и декремента
Операции инкремента и декремента не всегда уместны, так как могут вызывать следующие основные проблемы:
- длинный и сложный для восприятия программный код;
- трудноуловимые баги.
Наглядно представить усложнение кода можно в следующем примере:
- int x = a++ + (b— * f— — —g) + g++ * d—
Найти ошибку в таком коде достаточно проблематично, особенно если вы пытаетесь разобраться в модуле, который писал другой разработчик.
Вторая проблема является гораздо более коварной и требует детального рассмотрения. Обратите внимание на следующий пример:
int a = 2;
int b = a++ + (—a * ++a);
Какое значение у b? Разберемся. Только не компилируйте эти строки до знакомства с этапами осуществления вычислений.
- Сначала выполняем действия в скобках, так как они являются приоритетными. Получаем: –a * ++a = 1 * 2 = 2.
- Решаем далее: b = a++ + 2, a = 2. b = 2 + 2 = 4.
- На этом этапе проверим правильность решения в компиляторе. Он выводит ответ: 8.
На этом сюрпризы не закончились. Со школьной скамьи каждому знакомо правило коммутативности, которое звучит следующим образом: «От перемены мест слагаемых сумма не меняется». Проверим его на коде:
int b = (—a * ++a) + a++;
Компилятор выдаст нам результат 4. Можно сказать, что инкременты и декременты играют с математикой.
Вероятно, программист догадается первым делом произвести операцию a++. Остальные операции нужно совершать после нее. Тогда получится следующее: b = 2 + (—a * ++a) при a = 3; b = 2 + (2 * 3) = 8.
Итак, вычисления сходятся, но возникает противоречие с документацией Java по вопросу приоритетности скобок перед другими операциями. Возникает вопрос: документация содержит ошибочную информацию?
Это связано с тем, что данные арифметические операции имеют побочные эффекты, о которых мы упоминали в рекомендациях. Они оказывают влияние на программную среду и изменяют ее. Побочные эффекты, во-первых, влекут за собой трудноуловимые ошибки. Во-вторых, компилятор не берет их в расчет.
Читайте также!
Компилятор представляет собой программу, которая переводит текст, написанный программистом в машинные коды. В Java он делает форму текста проще, а в машинные коды переводит интерпретатор. У компилятора есть встроенный набор оптимизаций или действий, которые повышают производительность кода и делают его наиболее эффективным. Например, ленивые вычисления. Они работают для логического оператора И/ИЛИ и происходят слева направо. Если ответ уже ясен, то можно не продолжать вычислять.
В выражении 0 И (1 ИЛИ 0) уже после первого 0 нет смысла вычислять, так как в итоге И будет 0. Как раз из-за подобных функций компилятор считывает слева направо везде.
В приведённом нами примере компилятор видит b = a++ + и делает вывод, что помех для нахождения a++ нет. Побочный эффект инкремента увеличивает а, что влечет за собой ошибочный результат всех вычислений. Сначала нужно было считать действия в скобках.
Таким образом, 8 — это ошибочный ответ. Можно сделать вывод о том, что правильный — 4. На самом деле нет. Время для очередного откровения: верного ответа нет. Формулировка «результат не определен» означает, что нельзя сказать с уверенностью, что будет при выполнении строки кода. Объясним, почему. Это связано с тем, что ленивые вычисления можно отключить. Если сделать это, то ответ будет 4. Если оставить данную функцию в настройках, то получится 8.
Получается, что в случае, если результат зависит от внешнего фактора (например, настройки), то полагаться на него нельзя. Именно поэтому можно говорить о неопределенности.
Описанные выше проблемы свидетельствуют о том, что инкремент и декремент уместны не всегда.
Их следует использовать в следующих случаях:
- в цикле for;
- если операторы занимают всю строку.
Писать в программном коде i++ можно без сомнений, так как побочного эффекта не будет. При этом лучше не применять инкремент и декремент в составных выражениях.
Итак, арифметические операции инкремент и декремент не является сложными, если разобраться во всех тонкостях. При написании кода можно не применять их, но продвинутому программисту эти знания однозначно пригодятся.
Хотите получить одну из самых востребованных профессий в 2023 году? Станьте веб-разработчиком! Всего за 9 месяцев обучения вы познакомитесь с веб-технологиями, изучите популярные языки программирования и сможете самостоятельно создавать адаптивные сайты и интерактивные веб-приложения. Не упустите возможность стать специалистом одной из самых высокооплачиваемых и актуальных направлений. Присоединяйтесь к нам уже сейчас!