Различия между циклами for и while
Объясните пожалуйста различия между циклами for и while .
Если можно простым языком. Спасибо.
На примере функции range(n) :
В цикле for i in range(n) в переменную i будет поочередно записываться каждое значение из диапазона range(n) , например:
Сначала i принимает значение 0 , затем 1 , и так пока не дойдем до n .
Также циклом for можно пройтись по любому итерабельному объекту, например:
В переменную i поочередно будет записаны значения из списка array .
Цикл while работает немного иначе, он проверяет условие на истинность, while x < 10 — на каждой итерации цикла, будет осуществлена проверка x < 10 , если это так, цикл пойдет дальше, на примере того же range(n) :
На каждой итерации мы проверяем меньше ли переменная i чем 3 , если это так, то выводим значение переменной i и прибавляем к ней единицу, повторяем это пока проверка на i < 3 не вернёт False . Мы по сути говорим, пока что-то истинно, то выполняй какие то действия.
Помните пример с циклом for когда мы проходили по списку? С while дело обстоит иначе, нам нужно вытягивать из списка элементы по их индексам, т.е в условие будет выглядеть так: while i < len(array) , функция len(iterable) вернёт нам кол-во элементов в списке, на примере того же array :
Чтобы определить бесконечный цикл while , нужно указать такое условие, которое всегда истинно, например while True .
С циклом for все сложнее, бесконечный цикл явно указать нельзя, так как цикл for закончит свою работу тогда, когда пройдет по всем элементам объекта, следовательно нужно ему передать такой объект, в котором бесконечно элементов, тут нам помогут генераторы, говорить о них детально я не буду, так как тема довольно обширная, лишь покажу небольшой пример с модулем itertools :
Таким образом мы определили бесконечный цикл for , count также принимает 2 необязательных аргумента, start число с которого начнём итерацию, и step собственно шаг.
1.6. Инструкции. Условные операторы. Циклы
Как вы уже видели в предыдущих частях выполнение программы на C++ состоит из последовательных инстркций. Инструкции выполняются одна за другой. Тем не менее, несмотря на это, при определенных оптимизациях компилятор может попытаться съоптимизировать выполнение инстуркций и приведенный ниже пример не рекомендуется использовать на практике:
Вложенная видимость
Можно объявлять блоки (с помощью фигурных скобок) и в них объявлять переменные с уже сипользованным именем. В этом случае все манимпуляции с “новой” переменной никак не повлияют на переменную вне блока:
Условные операторы ветвления if/else
Самыми простыми условными ветвлениями в языке С++ являются стейтменты if/else. Они выглядят следующим образом:
При определенных сценаряих можно написать и проверку в else, но злоупотребять этим не стоит, так как код превразается не сильно читаемым (спагетти):
С++ предоставляет специальных тернарный оператор (? :), который может упростить выражение сверху (оставив функционал прежним):
Циклы for, while
Основным циклом в “классическом” C++ является цикл for. Общая его сигнатура следующая:
Например следующая инструкция считает сумму квадратов от 0 до 10 (не включительно)
В случае, когда нам необходимо задать только условия остановки данных код можно переписать с помощью цикла while:
Цикл do-while
Цикл do-while отличается от цикла while тем, что он гарантирует выполнение одного прогона, если даже условие в while уже не выполняется. В качестве примера рассмотрите следующие выражения:
PHP: типы циклов
Циклы в PHP используются для выполнения одного и того же блока кода определенное количество раз. PHP поддерживает следующие четыре типа циклов:
- for — выполняет блок кода определенное количество раз;
- while — выполняет блок кода, если и до тех пор, пока заданное условие истинно;
- do…while — выполняет блок кода один раз, а затем повторяется до тех пор, пока истинно специальное условие;
- foreach — выполняет блока кода для каждого элемента массива.
Посмотрим, как ключевые слова continue и break используются для управления выполнением цикла.
Оператор цикла for
Оператор for используется, когда вы знаете, сколько раз хотите выполнить оператор или блок операторов.
Синтаксис
Выполнением команды инициализации устанавливается начальное значение счетчика, указывающего количество итераций цикла. Для этого здесь может быть объявлена переменная, которую традиционно принято называть $i .
Пример
Следующий код делает пять итераций, изменяя присвоенное значение двух переменных на каждом проходе цикла:
Это приведет к следующему результату:
Оператор цикла while
Оператор while выполняет блок кода, если и до тех пор, пока тестовое выражение истинно.
Если тестовое выражение истинно, то блок кода будет выполнен. После выполнения кода тестовое выражение будет снова оценено, и цикл будет продолжаться до тех пор, пока тестовое выражение не окажется ложным.
Синтаксис
Пример
В этом примере кода значение переменной уменьшается на каждой итерации цикла, а значение счетчика увеличивается, пока не достигнет 10, когда оценка будет ложной и цикл завершится.
Это приведет к следующему результату:
Оператор цикла do…while
Оператор do…while выполнит блок кода хотя бы один раз, после чего будет повторять цикл до тех пор, пока условие будет истинным.
Синтаксис
Пример
В следующем примере кода значение переменной i хотя бы один раз увеличится, после чего будет продолжать возрастать до тех пор, пока будет меньше 10.
Это приведет к следующему результату:
Оператор цикла foreach
Оператор foreach используется для перебора массивов. При каждом проходе значение текущего элемента массива присваивается $value , а указатель массива перемещается на единицу, и при следующем проходе обрабатывается следующий элемент.
Синтаксис
Пример
Попробуйте в следующем примере перечислить значения массива:
Это приведет к следующему результату:
Оператор break
Ключевое слово PHP break используется для преждевременного завершения выполнения цикла.
Оператор break располагается внутри блока оператора. Он дает полный контроль над циклом, позволяя вам выйти из него в любой момент. После выхода из цикла будет выполнен следующий за ним оператор.
Пример
В следующем примере условие проверки становится истинным, когда значение счетчика достигает 3, и цикл завершается.
Это приведет к следующему результату:
Оператор continue
Ключевое слово PHP continue используется для остановки текущей итерации цикла, но не завершает цикл.
Как и break , оператор continue располагается внутри блока операторов, содержащего код, который выполняет цикл, и предваряется условным тестом. При выполнении цикла, в котором встречается оператор continue , остальная часть кода цикла пропускается и начинается следующий цикл.
Пример
В следующем примере цикл печатает значение массива, но для условия, которое становится истинным, он просто пропускает код и печатает следующее значение:
Циклы while и for
При написании скриптов зачастую встаёт задача сделать однотипное действие много раз.
Например, вывести товары из списка один за другим. Или просто перебрать все числа от 1 до 10 и для каждого выполнить одинаковый код.
Для многократного повторения одного участка кода предусмотрены циклы.
Небольшое объявление для продвинутых читателей.
В этой статье рассматриваются только базовые циклы: while , do..while и for(..;..;..) .
Если вы пришли к этой статье в поисках других типов циклов, вот указатели:
- См. for…in для перебора свойств объекта.
- См. for…of и Перебираемые объекты для перебора массивов и перебираемых объектов.
В противном случае, продолжайте читать.
Цикл «while»
Цикл while имеет следующий синтаксис:
Код из тела цикла выполняется, пока условие condition истинно.
Например, цикл ниже выводит i , пока i < 3 :
Одно выполнение тела цикла по-научному называется итерация. Цикл в примере выше совершает три итерации.
Если бы строка i++ отсутствовала в примере выше, то цикл бы повторялся (в теории) вечно. На практике, конечно, браузер не позволит такому случиться, он предоставит пользователю возможность остановить «подвисший» скрипт, а JavaScript на стороне сервера придётся «убить» процесс.
Любое выражение или переменная может быть условием цикла, а не только сравнение: условие while вычисляется и преобразуется в логическое значение.
Например, while (i) – более краткий вариант while (i != 0) :
Если тело цикла состоит лишь из одной инструкции, мы можем опустить фигурные скобки <…>:
Цикл «do…while»
Проверку условия можно разместить под телом цикла, используя специальный синтаксис do..while :
Цикл сначала выполнит тело, а затем проверит условие condition , и пока его значение равно true , он будет выполняться снова и снова.
Такая форма синтаксиса оправдана, если вы хотите, чтобы тело цикла выполнилось хотя бы один раз, даже если условие окажется ложным. На практике чаще используется форма с предусловием: while(…) <…>.
Цикл «for»
Более сложный, но при этом самый распространённый цикл — цикл for .
Выглядит он так:
Давайте разберёмся, что означает каждая часть, на примере. Цикл ниже выполняет alert(i) для i от 0 до (но не включая) 3 :
Рассмотрим конструкцию for подробней:
| часть | ||
|---|---|---|
| начало | let i = 0 | Выполняется один раз при входе в цикл |
| условие | i < 3 | Проверяется перед каждой итерацией цикла. Если оно вычислится в false , цикл остановится. |
| тело | alert(i) | Выполняется снова и снова, пока условие вычисляется в true . |
| шаг | i++ | Выполняется после тела цикла на каждой итерации перед проверкой условия. |
В целом, алгоритм работы цикла выглядит следующим образом:
То есть, начало выполняется один раз, а затем каждая итерация заключается в проверке условия , после которой выполняется тело и шаг .
Если тема циклов для вас нова, может быть полезным вернуться к примеру выше и воспроизвести его работу на листе бумаги, шаг за шагом.
Вот в точности то, что происходит в нашем случае:
В примере переменная счётчика i была объявлена прямо в цикле. Это так называемое «встроенное» объявление переменной. Такие переменные существуют только внутри цикла.
Вместо объявления новой переменной мы можем использовать уже существующую:
Пропуск частей «for»
Любая часть for может быть пропущена.
Для примера, мы можем пропустить начало если нам ничего не нужно делать перед стартом цикла.
Можно убрать и шаг :
Это сделает цикл аналогичным while (i < 3) .
А можно и вообще убрать всё, получив бесконечный цикл:
При этом сами точки с запятой ; обязательно должны присутствовать, иначе будет ошибка синтаксиса.
Прерывание цикла: «break»
Обычно цикл завершается при вычислении условия в false .
Но мы можем выйти из цикла в любой момент с помощью специальной директивы break .
Например, следующий код подсчитывает сумму вводимых чисел до тех пор, пока посетитель их вводит, а затем – выдаёт:
Директива break в строке (*) полностью прекращает выполнение цикла и передаёт управление на строку за его телом, то есть на alert .
Вообще, сочетание «бесконечный цикл + break » – отличная штука для тех ситуаций, когда условие, по которому нужно прерваться, находится не в начале или конце цикла, а посередине или даже в нескольких местах его тела.
Переход к следующей итерации: continue
Директива continue – «облегчённая версия» break . При её выполнении цикл не прерывается, а переходит к следующей итерации (если условие все ещё равно true ).
Её используют, если понятно, что на текущем повторе цикла делать больше нечего.
Например, цикл ниже использует continue , чтобы выводить только нечётные значения:
Для чётных значений i , директива continue прекращает выполнение тела цикла и передаёт управление на следующую итерацию for (со следующим числом). Таким образом alert вызывается только для нечётных значений.
Цикл, который обрабатывает только нечётные значения, мог бы выглядеть так:
С технической точки зрения он полностью идентичен. Действительно, вместо continue можно просто завернуть действия в блок if .
Однако мы получили дополнительный уровень вложенности фигурных скобок. Если код внутри if более длинный, то это ухудшает читаемость, в отличие от варианта с continue .
Обратите внимание, что эти синтаксические конструкции не являются выражениями и не могут быть использованы с тернарным оператором ? . В частности, использование таких директив, как break/continue , вызовет ошибку.
Например, если мы возьмём этот код:
…и перепишем его, используя вопросительный знак:
…то будет синтаксическая ошибка.
Это ещё один повод не использовать оператор вопросительного знака ? вместо if .
Метки для break/continue
Бывает, нужно выйти одновременно из нескольких уровней цикла сразу.
Например, в коде ниже мы проходимся циклами по i и j , запрашивая с помощью prompt координаты (i, j) с (0,0) до (2,2) :
Нам нужен способ остановить выполнение, если пользователь отменит ввод.
Обычный break после input лишь прервёт внутренний цикл, но этого недостаточно. Достичь желаемого поведения можно с помощью меток.
Метка имеет вид идентификатора с двоеточием перед циклом:
Вызов break <labelName> в цикле ниже ищет ближайший внешний цикл с такой меткой и переходит в его конец.
В примере выше это означает, что вызовом break outer будет разорван внешний цикл до метки с именем outer .
Таким образом управление перейдёт со строки, помеченной (*) , к alert(‘Готово!’) .
Можно размещать метку на отдельной строке:
Директива continue также может быть использована с меткой. В этом случае управление перейдёт на следующую итерацию цикла с меткой.
Метки не дают возможности передавать управление в произвольное место кода.
Например, нет возможности сделать следующее:
Директива break должна находиться внутри блока кода. Технически, подойдет любой маркированный блок кода, например:
…Хотя в 99.9% случаев break используется внутри циклов, как мы видели в примерах выше.
К слову, continue возможно только внутри цикла.
Итого
Мы рассмотрели 3 вида циклов:
- while – Проверяет условие перед каждой итерацией.
- do..while – Проверяет условие после каждой итерации.
- for (;;) – Проверяет условие перед каждой итерацией, есть возможность задать дополнительные настройки.
Чтобы организовать бесконечный цикл, используют конструкцию while (true) . При этом он, как и любой другой цикл, может быть прерван директивой break .
Если на данной итерации цикла делать больше ничего не надо, но полностью прекращать цикл не следует – используют директиву continue .
Обе этих директивы поддерживают метки, которые ставятся перед циклом. Метки – единственный способ для break/continue выйти за пределы текущего цикла, повлиять на выполнение внешнего.
Заметим, что метки не позволяют прыгнуть в произвольное место кода, в JavaScript нет такой возможности.