InCode#A3: Инкремент и декремент. Циклы

Вы думаете, что после рассмотрения логических конструкций вы можете уже приступить к написанию своих программ? Пока что нет. Не владея циклами и парочкой вспомогательных конструкций, написать серьёзную программу не выйдет.

Постановка проблемы

Зачем нам могут понадобиться циклы? Представьте ситуацию: вы пишите программу и вам требуется вывести на экран 50 раз слово “Привет”. Конечно, вы можете написать это вручную 50 раз (“Ctrl + C” и “Ctrl + V” никто не отменял). Но программирование создано для упрощения жизни и автоматизации процессов. Для подобного рода задач и существуют циклы.

Инкремент и декремент

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

Первая рассмотренная конструкция ー инкремент. Эта операция имеет вид “++”. Суть этой операции ー увеличение на единицу переменной, к которой она была применена. Иными словами, следующие команды выполняют одно и то же действие:

Целочисленная А=6;
А = А + 1;
Целочисленная А=6; А += 1;Целочисленная А = 6; А++;

Инкремент имеет два вида. Это “префиксный инкремент” и “постфиксный инкремент”. Они отличаются одной деталью, которая крайне важна и понимание которой упростит вашу жизнь в дальнейшем.

Префиксный инкремент записывается как “++А”, где “А” ー это наша целочисленная переменная. Вы можете уже догадаться, в чём отличие между префиксным и постфиксным инкрементом.

Оно заключается в том, что в префиксном инкременте сначала выполняется инкремент, а после всё остальная математика. Ну а в постфиксном инкременте наоборот. Сначала выполняется вся математика, а позже инкремент.

На самом деле все очень просто. Давайте я приведу пример того, как это будет выглядеть при запуске на реальном языке.

Для этого я введу некоторую конструкцию

“НаДисплей(Информация)”

Эта конструкция называется функцией и работу с ними мы разберем в дальнейшем. При вызове этой функции в скобках мы должны написать информацию, которую хотим вывести на экран.

Теперь непосредственно код:

КодРезультат на экране
Целочисленная А = 5;
НаДисплей (A);
НаДисплей (4 + ++A);
НаДисплей (A);

5
1
0
6

Почему же так произошло? Потому, что при вызове вычислений “4 + ++A” переменная А увеличилась на единицу и стала быть равной 6. Затем просто складываются 6 и 4, получается 10.

Результат изменится, если мы заменим префиксный инкремент на постфиксный.

КодРезультат на экране
Целочисленная А = 5;
НаДисплей (A);
НаДисплей (4 + A++);
НаДисплей (A);

5
9
6

Наверное, вы догадываетесь, почему так произошло. Но я всё равно рассмотрю это. В вычислениях “4 + A++” мы складываем только 5 и 4, ибо лишь после вычисления всей математики и выполнения функции у нас сработает инкремент. Так происходит потому, что операция инкремента имеет наименьший приоритет исполнения. Как только результат появился на экране, А увеличилась на единицу.

Ещё мы должны пройти декремент. Это обратная инкременту операция и обозначается она как “—”. Существует префиксный и постфиксный декремент.

Код для примера:

Префиксный декремент:

КодРезультат на экране
Целочисленная А = 5;
НаДисплей (4 + —A);
НаДисплей (A);

8
4

Постфиксный декремент:

КодРезультат на экране
Целочисленная А = 5;
НаДисплей (4 + A—);
НаДисплей (A);

9
4

Вы заметили, как небольшая ошибка в знаках может повлиять на работу программы. Поэтому старайтесь следить за логикой и не упускайте из вида такие мелочи. Это может обойтись вам очень дорого.

Циклы

Существует три типа циклов (по крайней мере в Си подобных языках программирования). Это цикл перечисления (for), цикл с предусловием (while) и  цикл с постусловием (while do).

Цикл перечисления for имеет следующую конструкцию:

for (Инициализация; Логическая проверка; Итератор) { 
    Тело цикла 
}

В “Инициализации” пишется код, который выполняется единожды при запуске цикла. Обычно туда вставляют инициализацию переменных, которые изменяются в цикле.
При истинности “Логической проверки” цикл работает. Обычно тут устанавливают сравнение или другие конструкции.
“Итератор” ー это действие, выполняемое после каждой итерации цикла. Обычно это инкремент или декремент той переменной, которую мы объявили в блоке “Инициализация”.
“Тело цикла” содержит в себе код, который мы должны исполнить несколько раз.

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

Задача №1. Вывести на экран числа, которые находятся в промежутке от 0 до 100 и делятся без остатка на 3 и 2 одновременно.

Для начала нужно написать конструкцию, которая будет определять, делится ли число на 3 и 2 без остатка. Я предлагаю использовать математический оператор модуля “%”. Если взять некоторое число по модулю 3, то мы получаем в результате только числа в диапазоне от -2 до 2, причем если число кратно модулю (в нашем случае модуль 3), то результат будет равен 0.

Разберем на примере. Я напишу ряд чисел от -5 до 10 и применю к каждому числу оператор модуля “% 3”:

-5-4-3-2-1012345678910
-2-10-2-101201201201

Попробуйте применить к этому ряду (от -5 до 10) модуль оператор модуля “% 2”. Вот что получилось у меня:

-5-4-3-2-1012345678910
-10-10-101010101010

Пример кода:

Целочисленный input;

Если (input % 3 == 0 And input % 2 == 0) Тогда{     НаДисплей(“Число:”, input, “делится на 3 и 2 без остатка”);
}

Осталось перебрать все числа в диапазоне от 0 до 100, применив к ним этот код.

Для этого необходимо определить цикл for. Вот как я это сделаю:

for (Целочисленный i = 0; i <= 100; i++){    
    //А тут тело цикла
}
/*Удобно ставить комментарии “//” в коде, чтобы при чтении лучше понимать суть того или иного фрагмента. В Си подобных языках однострочный комментарий обозначается двойным слешем “//”. Чтобы закомментировать кусок кода, нужно в начале поставить “/*” и в конце “*/”.*/

Вот так просто это делается. Мы указали, что начинаем отсчёт от 0 и ведём ровно до тех пор, пока число меньше либо равно 100 (всего будет 101 срабатывание). Каждый шаг увеличивается на 1 (мы могли записать “i += 1” или  “i = i + 1”, но ведь: “i++” удобнее).

Осталось объединить эти два блока кода кода:

for (Целочисленный i = 0; i <= 100; i++){
    Если (i % 3 == 0 And i % 2 == 0) Тогда {
        НаДисплей(“Число:”, i, “делится на 3 и 2 без остатка”); 
    }
}

Задача решена.

Для закрепления я рассмотрю еще одну задачу,

Задача №2. Найти сумму всех четных чисел в диапазоне от 25 до 125.

Эту задачу можно решить множеством способов (как и любую задачу программиста), но я выберу два наиболее наглядных.

Вариант 1. Он максимально близок к тому, что мы рассмотрели выше:

Целочисленная Sum = 0;

for (Целочисленный i = 25; i <= 125; i++){
    Если (i % 2 == 0) Тогда {
        Sum += i;    
    }
}

НаДисплей(“Сумма чётных чисел в диапазоне от 25 до 125 = “, Sum);

Мы сделали все то же самое. Определили диапазон и проводим каждый раз проверку на четность.

Вариант 2. Предыдущий алгоритм универсален, но всегда нужно стремиться к упрощению. Пример оптимизации задачи:

Целочисленная Sum = 0;

for (Целочисленный i = 26; i <= 124; i += 2){
    Sum += i;
}

НаДисплей(“Сумма чётных чисел в диапазоне от 25 до 125 = “, Sum);

Из математики нам известно, если к четному числу прибавить любое другое четное число, то в результате получается также четное число. Тогда определим первое и последнее четное число в нашем диапазоне (от 25 до 125). Первое четное число 26. Последнее число 124. После мы создаем цикл for с шагом равным 2 (минимальное четное число). Таким образом, цикл работает в диапазоне от 26 до 124 включительно.

Сравним сложность вычислений:

Вариант 1Вариант 2
100 срабатываний цикла
100 проверок
50 суммирований
50 срабатываний цикла
0 проверок
50 суммирований

На этом с циклами типа for я предлагаю закончить. Но впереди у нас ещё два типа циклов, с которыми нужно разобраться.

Цикл с предусловием имеет следующую конструкцию:

while (Логическая проверка) { 
    Тело цикла 
}

Этот цикл работает, пока выполняется условие, которое мы в него ввели.

Задача №3. Найдите ближайшую (превышающее число) степень двойки.

Для начала давайте перечислим несколько степеней двойки:

2, 4, 8, 16, 32, 64, 128, …

Допустим мы ввели число 12. Тогда ближайшая превышающая степень двойки 16. Если введем 25, то результат должен быть 32.
Реализация:

Целочисленный input;
Целочисленный output = 2;

while ( output < input ){
     output *= 2;
}

НаДисплей(output);

Мы создали переменную output, которая равна 2^1 (просто 2). Далее постоянно возводим ее в следующее степень и сравниваем с введенным числом.

Цикл с предусловием имеет следующую конструкцию:

do { 
    Тело цикла 
} while (Логическая проверка)

Можно догадаться, что отличие данного цикла от цикла с предусловием в том, что сначала идёт выполнение, а потом уже проверка.

Задача №4. Вывести на экран числа от 0 до введённого нами числа и посчитать их сумму.

Целочисленный input;
Целочисленный output = 0;
Целочисленный Sum = 0;

do{
    НаДисплей(output);
    output++;
    Sum += output;
} while ( output <= input )

НаДисплей(Sum);

Управляющие операторы

При работе с циклами могут возникнуть ситуации, когда вам нужно пропустить итерацию или даже прервать цикл досрочно.

“Пропустить” пропускает одну итерацию цикла. Это может пригодиться, когда некоторые ситуации можно не просчитывать или они могут привести к логической ошибке.

Оператор «Прервать» необходим для досрочного выхода из цикла. Его можно использовать в ситуациях, когда есть риск переполнения типа данных или при слишком долгой работе цикла.

Вы должны учесть, что эти операторы нарушают логику работы программы и желательно стараться их избегать. Тот же функционал можно заключить в блоки “Если”, тем самым уточняя логику, а не нарушая ее.

InCode#A3: Инкремент и декремент. Циклы

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *