9. 1. Программирование циклических алгоритмов. Цикл по коллекции (for)
§ 9.1. Программирование циклических алгоритмов. Цикл по коллекции (for)
Цикл по переменной (или с параметром) for применяется в том случае, когда прежде выполнения инструкций тела цикла, становится известным количество шагов, которые должен выполнить этот цикл. Название цикла связано с тем, что в заголовке этого цикла всегда используется счетчик. Счетчику ( i ) присваивается начальное значение ( a ). В зависимости от языка, на каждом шаге цикла счетчик получает приращение ( n , целое или дробное). Цикл заканчивает свою работу, когда значение счетчика приобретает максимально допустимое значение ( b ), определяемое в условии. Обычно блок-схема цикла изображается с помощью блока “модификация”:
Инструкция for
В python цикл по переменной реализует инструкция for . Синтаксис этой инструкции выглядит необычным образом:
Дело в том, что цикл for в python предназначен для обхода последовательностей (англ. sequence) любого итерируемого типа.
Последовательность в for можно определять явно или использовать по имени. Приведем пример, в котором последовательность определяется явно.
Задача 1. Вывести на экран все степени числа 2 от 1 до 10 .
На каждом шаге цикла переменная i поочередно принимает все значения элементов последовательности. Когда будет передано значение последнего элемента последовательности, итерации прекратятся и цикл завершит свою работу.
Так же, как и цикл while , инструкция цикла for имеет необязательный блок else .
Функция range()
Чтобы расширить применение цикла for на задачи не относящиеся к обработке последовательностей и, тем самым, сделать его более универсальным, в python разработан класс range . Его назначение создавать произвольные целочисленные последовательности в виде прогрессий. Хотя в python и принято причислять range к типу последовательностей, но, на самом деле, последовательности, созданные range() , не являются таковыми. Дело в том, что range определяет только правила построения последовательности, сами же элементы в памяти не сохраняются.
Функция range() может применяться с одним, двумя или тремя аргументами:
- range(a) – создается последовательность от 0 до a — 1 – [0, a-1] ( a – не входит);
- range(a, b) – создается последовательность от a до b – [a, b) ( b – не входит);
- range(a, b, n) – создается последовательность от a до b – [a, b) с шагом n ( b – не входит, шаг может быть отрицательным).
Рассмотрим пример из учебника.
Задача 2. Дано целое n и действительное a . Вычислить a n (целую степень действительного числа).
Блок-схема
В данной программе значение счетчика не используется. Переменная цикла i проходит по всем элементам последовательности от 0 до n-1 . В результате, цикл сделает n итераций и мы получим искомое значение степени.
Часто значение счетчика используется в теле цикла для изменения какой-либо величины. Приведем пример с черепахой. В этой программе значение счетчика используется для изменения радиуса окружности на каждой итерации.
Задача 3. Построить в центре холста n разноцветных окружностей с общим центром так, чтобы окружность меньшего радиуса находилась поверх окружности с большим радиусом. Радиус r самой большой окружности ввести с клавиатуры.
Возможный вывод
r = 250
n = 9
Вложенные циклы for
Для вложенных циклов, работающих от счетчика, чаще всего применяется цикл for , так как он представляет эту структуру в более компактной форме. Приведем простой пример.
Задача 4. Вывести таблицу умножения шестнадцатеричных чисел от 1 до 10 (1610).
Блок-схема
Обратите внимание, что переменные внешнего и вложенного циклов должны иметь разные имена!
Вывод по образцу с помощью for тоже возможен.
Задача 5. Вывести числовой треугольник по образцу:
Вывод см. выше
Здесь длина последовательности, создаваемой функцией range() для вложенного цикла, будет зависеть от значения i на текущей итерации.
Рассмотрим более сложный пример переборного алгоритма реализованного с помощью вложенных for .
Задача 6. Вывести таблицу истинности для логического выражения:
not(a v b) v (a ^ c) ,
где a , b и c – это логические переменные.
Как видите, мы оказались правы – переборные циклы выполненные с помощью for выглядят значительно компактнее аналогичных c циклом while .
Заметим, что цикл одного типа может быть вложен в цикл другого типа.
Задача 7. Найти натуральное число от 100 до 1000 с максимальной суммой делителей
Рассмотрим пример с черепахой, которая мостит треугольную плитку на холсте с помощью вложенных циклов for .
Задача 8. Составить программу мощения черепахой равносторонней треугольной плиткой всей площади холста. Размер стороны плитки определить с клавиатуры.
Вывод
d = 70
Замечаем, что в этой программе тоже наличествует повторяющийся код. На следующем уроке мы решим эту проблему.
Цикл for
Данный цикл в основном используется когда известно точное количество повторений. Этот цикл ещё называют циклом со счётчиком.
Синтаксис цикла «for»:
Основные части конструкции цикла «for»:
- инициализация — это выражение, которое выполняется один раз перед выполнением цикла; обычно используется для инициализации счётчика;
- условие — это выражение, истинность которого проверяется перед каждой итерацией; если выражение вычисляется как истина , то выполняется итерация; в противном случае цикл «for» завершает работу;
- финальное выражение — это выражение, которое выполняется в конце каждой итерации; обычно используется для изменения счетчика;
- тело цикла — инструкции, выполнение которых нужно повторять.
Рассмотрим пример цикла, который выведет в консоль числа от 1 до 8:
- инициализация: var i = 1 (объявление переменной i и присвоение ей значения 1);
- условие выполнения цикла: i <= 8 (пока значение переменной i меньше или равно 8);
- финальное выражение, которое нужно выполнять в конце каждой итерации: i++ (увеличение значение переменной i на 1);
- инструкция, которую нужно выполнять: console.log(i) (выведение значения счётчика в консоль).
При этом если тело цикла состоит из одной инструкции, то её можно не заключать в фигурные скобки .
Таким образом, пример, приведённый выше, можно записать ещё так:
Необязательные части цикла цикла «for».
В «for» все части цикла являются не обязательными.
Например, можно пропустить выражение инициализации:
В этом случае инициализацию переменной можно вынести за пределы цикла.
Условие в «for» тоже является не обязательным. Без условия цикл будет выполняться бесконечное количество раз. В этом случае чтобы его прервать (выйти из цикла) необходимо использовать инструкцию break .
Финальное выражение в «for» также является не обязательным. Счётчик цикла в этом случае можно, например, изменять в теле.
В «for» можно вообще опустить 3 выражения (бесконечный цикл):
Кроме этого, в качестве тела цикла «for» можно использовать пустое выражение ( ; ). Это используется, когда вам не нужно выполнять ни одной инструкции.
Пустое выражение в этом случае рекомендуется дополнительно снабжать комментарием:
Пример использования цикла «for» для перебора элементов массива:
Пример, в котором выведем таблицу умножения в консоль. Для реализации этого примера будем использовать вложенные циклы.
Цикл называется вложенным, если он находится в теле другого цикла.
Операторы continue и break
Бывают ситуации, когда вам нужно экстренно прервать выполнение цикла внутри блока цикла, не дожидаясь до перехода к блоку проверки условий. Для этого можно использовать оператор break:
Если мы просто хотим остановить ход выполнения текущей итерации, но не выйти из цикла, а перейти к блоку проверки условий, то должны использовать оператор continue:
Операторы continue и break могут использоваться со всеми вариантами циклов FOR и WHILE.
Очень важно, когда мы знакомились с оператором switch, мы использовали оператор принудительного выхода break. В циклах while, do while и for, мы его так же можем использовать. Однако, делать это не рекомендуется.
Помимо оператора break, существует оператор continue. Он отличается тем, что заставляет принудительно выйти из текущей итерации цикла. Точно так же как и break, continue использовать не рекомендуется.
Посмотрите на изображение выше. На нем представлены схемы действия этих двух операторов. И последствия их использования внутри цикла.
Все дело в том, что мы используем циклы для определенных задач, а применение break либо continue, нарушает наши планы. И мы не сможем предсказать логику действия нашего цикла.
Противостояние двух языков программирования: С и Turbo Pascal
Как правило, уважающий себя программист знает несколько языков. К примеру, это могут быть С++, Turbo Pascal, Delphi, Java и т. д. Противостояние двух из них было ярко выражено еще в 80-е гг. (С и турбо паскаль). В конце ХХ века такая же борьба наблюдалась между Си++ и Java.
В виртуальном пространстве среди трех десятков языков программирования можно выделить три самые яркие пары, противостояние которых поражало величайшие умы киберпространства: алгол-60 и фортран, Pascal и C, Java и С++. Конечно, эти ощущения субъективные, но в тот или иной период один из пары был лидером. Это объяснялось требованиями промышленности и необходимости в том или ином программном продукте. В 70-х гг. «управлял миром» фортран, в 80-х – Turbo Pascal, в 90-х – С++. Конечно, ни один из них не «умер». Скорее, они преобразовались в усовершенствованные программные продукты.
При изучении языков программирования можно заметить, что в некоторых темах синтаксис схож. Так, циклы с параметром в C аналогичны подобным конструкциям в Pascal, за исключением некоторых моментов.
Интересно, что разработчики Turbo Pascal (Старый Свет) пользовались результатами наработок американских ученых, в то время как в Новом Свете активно применяли итоги исследований европейских специалистов. В Европе разработчики ратуют в большей степени за чистоту и компактность языков программирования, а американские умы склоняются больше к использованию новомодных веяний в написании кода.