Последние
(OFF) gjm2mjg (B) 14 апр 2018

Циклы

Для работы очень часто помимо прочих прелестей необходимо повторять некоторые действия определенное количество раз, еще и с разными исходными данными. С одной стороны код этого действия можно продублировать несколько раз, при необходимости подставляя необходимые исходные данные, но это не есть хорошо уже по той причине, что код неоправданно разрастается, причем очень быстро, что бьет как минимум по визуальному его восприятию. Более того, зачастую мы не знаем заранее точного количества повторений, и тут дублированием фрагмента кода не обойтись.
Для примера давайте рассмотрим такую простенькую задачу, как вывод квадратного корня диапазона чисел 1-5 (включительно). За расчет квадратного корня у нас отвечает стандартная функция PHP: sqrt(), поэтому приступаем к написанию кода:

<?php

echo sqrt(1) . '<br>';
echo sqrt(2) . '<br>';
echo sqrt(3) . '<br>';
echo sqrt(4) . '<br>';
echo sqrt(5) . '<br>';
Замечательно. В результате мы увидим на странице:

1
1.4142135623731
1.7320508075689
2
2.2360679774998
Но, как видите, код уже потерял свою визуальную красоту, что затрудняет дальнейшую работу с ним. Более того, что делать, если, например, необходимый диапазон для расчетов должен быть задан пользователем? Конечно, можно предоставлять пользователю выбор любого из заранее подготовленных диапазонов, но это во-первых будет ужасно в плане реализации и в плане качества самого кода; во-вторых предусмотреть все необходимые пользователю диапазоны таким образом с большим трудом хоть и удастся - это будет сущий ужас для программиста!

Для решения подобных сложностей каждый (наверное) ЯП предоставляет возможность не просто зацикливать фрагменты кода, а и указать необходимое количество их повторений (каждый такой повтор называется Итерацией), и возможность оперировать исходными данными кода в каждой итерации, и называется эта прелесть - циклы!

Предоставляемых языком программирования циклов несколько типов:
* с постусловием
* с предусловием
* со счетчиком

И конкретно PHP имеет еще один тип цикла: для перебора массивов.

Начнём, пожалуй, с самого распространённого и довольно лёгкого цикла, с предусловием - while(), имеющего следующий синтаксис:

while(<условие_повторения>) {
<повторяемый_код>
}

Принцип его работы очень прост: вначале происходит логический разбор <условия повторения> и если оно Истинно - выполняется итерация <повторяемый код>, иначе цикл завершается и выполнение кода продолжается со следующего за ним кода. Давайте рассмотрим пример его использования на примере описанной в начале статьи ситуации - расчет и вывод квадратного корня определенной последовательности чисел:

<?php

$number = 1; // начальное (и текущее) и...
$end = 5; // ...конечное значение последовательности чисел

echo 'Начало цикла<hr>';

while($number <= $end) {
echo sqrt($number) . '<br>';
$number++;
}

echo '<hr>Конец цикла';
Здесь цикл рассматривает условие повтора: значение переменной $number меньше или равно значению переменной $end - в самом начале выполнения цикла начальное (и текущее) значение $number равно единице - условие истинно и выполняется очередная (пока что первая) итерация: рассчитывается и выводится на страницу квадратный корень текущего значения переменной $number, затем её значение увеличивается на единицу ($number++) и всё повторяется заново, только на этот раз уже с другими исходными данными. Теперь значение $number равно целочисленной двойке, которая удовлетворяет условие повтора (меньше или равно пяти) и итерация выполняется снова. И так до тех пор, пока значение $number не станет больше пяти - шесть - тогда проверка условия повторения не будет Истиной и цикл завершится, и выполнение кода продолжится со следующего за ним кода, о чем свидетельствует выполнение выводящей на страницу текст "Конец цикла" строки кода.
Как видите, теперь мы имеем возможность менять исходные данные повторяющегося кода (в нашем случае это ряд чисел для расчета их квадратного корня) и, что не менее важно, влиять на точное количество повторений нашего кода указывая условия его повторения. Более того, при описании условия повторения цикла возможно использовать все те возможности, что и в условном операторе if() (за исключением ветвления с помощью elseif() и else), лишь бы результатом условного выражения было логическое значение (повторюсь, что для выполнение итерации необходимо, чтобы условие было Истинным!). Так что указывать условия возможно гораздо более хитро-мудрые, чем в рассмотренном примере. Обязательно поэкспериментируйте! =)

Это был цикл с предусловием - он вначале проверяет условие повтора и повторяемый код выполнится только если условие Истинно. То есть вполне вероятно, что цикл может не выполнится ни разу (например, когда условия повтора генерируются динамически по ходу работы программы), что в реальной работе подходит нам не всегда. Для таких случаев существует еще одна разновидность цикла while(), с постусловием - do..while. Его работа противоположна while(): вначале выполняется повторяемый код, и только после проверяется условие повтора, и если оно истинно - код повторяется еще раз. В таком случае повторяемый код выполнится хотя бы один раз! Синтаксис do..while не очень отличается от while(), и давайте перепишем рассмотренный выше код под него:

<?php

$number = 1; // начальное (и текущее) и...
$end = 5; // ...конечное значение последовательности чисел

echo 'Начало цикла<hr>';

do {
echo sqrt($number) . '<br>';
$number++;
}
while($number <= $end);

echo '<hr>Конец цикла';
Здесь всё немного наоборот, чем в while(): вначале выполняется блок кода do, затем проверяется условие while(), и если оно истинно, код do выполняется еще раз. Всё остальное в точности как и в случае с while().

Итак, циклы с пост- и пред-условиями мы рассмотрели. На очереди цикл со счетчиком - for(). Чем он - со счетчиком - отличается от циклов, рассмотренных выше? Для начала поговорим о том, что такое Счетчик - это самая обычная целочисленная переменная, значение которой постоянно меняется в зависимости от обстоятельств - например, можно увеличивать значение такой переменной каждую секунду и таким образом отсчитывать время. Циклы повторяют фрагмент кода и чтобы узнать сколько выполненных итераций (повторений) было произведено можно так же вести переменную-счетчик, и так же само с помощью переменной-счетчика можно прервать выполняющийся цикл... В примерах выше условие повтора циклов регулируется переменной-счетчиком $number, и тут проявляется отличие цикла for() от остальных - раньше мы "вели" счетчик "вручную", а for() берет эту задачу на себя и именно таким образом указывается его количество повторений, что станет ясно из последующих далее примеров. Но для начала рассмотрим его синтаксис:

for(<начальное_значение>; <конечное_значение>; <работа_со_счетчиком>) {
<повторяющийся_код>
}

Здесь начальное_значение - значение счетчика, с которым начнется выполнение цикла, и выполняться он будет до тех пор, пока сравнение текущего значения счетчика со значением конечное_значение будет Истинным, а меняться значение счетчика будет в части <работа_со_счетчиком>, что мы сейчас рассмотрим на следующем примере:

<?php

$number = 1; // начальное (и текущее) и...
$end = 5; // ...конечное значение последовательности чисел

echo 'Начало цикла<hr>';

for($i = $number; $i <= $end; $i++) {
echo sqrt($i) . '<br>';
}

echo '<hr>Конец цикла';
Здесь в условии цикла вначале создается переменная-счетчик $i, которая и будет регулировать его (цикла) повторение, и своё начальное значение она получает из переменной $number; затем указывается значение счетчика, при котором цикл должен завершиться - это значение $end; в последнем блоке меняется значение счетчика - в нашем случае оно увеличивается на единицу после каждой итерации. Так что теперь в нашем примере ход выполнения цикла такой: создается переменная $i со значением 1, устанавливается условие выхода: значение $i меньше или равно 5, и вставляется код, регулирующий значение счетчика. Условие повтора истинно уже в самом начале (значение $i == 1 - оно меньше 5), поэтому выполняется код расчета квадратного корня и вывод результата на страницу, только теперь мы передаём функции sqrt() не собственную переменную-счетчик как раньше ($number), а ту, которую ведет сам цикл. После выполнения итерации происходит работа над самим счетчиком и в нашем примере значение переменной $i увеличивается на единицу. Теперь $i равна двум и это так же соответствует нашему условию ($i меньше или равна пяти), и повторяющийся код выполняется снова. И как и в случае с предыдущими циклами так будет продолжаться до тех пор, пока значение $i не выйдет за пределы условия.
В отличие от while() и do..while(), в случае с for() мы не так свободны в описании условий его повторения, ибо нужно использовать числовые значения. И так же как и прежде, в for() мы имеем возможность вести одновременно несколько независимых счетчиков и регулировать ими условие выхода из цикла. Небольшой пример:

<?php

echo 'Начало цикла<hr>';

for($x = 1, $y = 1; $x <= 10, $y <= 30; $x++, $y += 2) {
echo "X: {$x}, Y: {$y}<br>";
}

echo '<hr>Конец цикла';
Здесь создается уже два счетчика - $x и $y - с одинаковыми значениями - 1; и оба используются в условии выхода из цикла: $x <= 10, а $y <= 30; и они оба увеличиваются, но только с разной скоростью: $x увеличивается на 1, а $y на 2. Завершится цикл когда истинными станут оба (!) условия выхода: для достижения необходимого значения $x понадобится десять итераций (значение станет равно 11), а $y - пятнадцать (31). Поэтому к моменту завершения цикла (когда истинными станут оба условия) значение $x будет 16, а $y - 31.

Теперь цикл foreach(), необходимый для обхода массивов, но для начала давайте рассмотрим суть вопроса. Допустим, есть у нас некий список (это массив с числовыми индексами) неких чисел, содержимое которого нам нужно вывести на страницу. С учетом теперешнего опыта работы с циклами это вообще пустяковое дело:

<?php

$list = [10, 20, 30];

$count = count($list); // получаем размер массива

/* for() */

for($i = 0; $i < $count; $i++) {
echo $list[$i] . '<br>';
}

/* while() */

$i = 0;
while($i < $count) {
echo $list[$i] . '<br>';
$i++;
}

/* do..while() */

$i = 0;
do {
echo $list[$i] . '<br>';
$i++;
}
while($i < $count);
Задачу очень упрощает то, что у массива числовые индексы (10 - под индексом 0, 20 - 1...) и даже если значения идут не с начала (с нулевого индекса) и не по-порядку, в крайнем случае можно вывести значения массива его перебором "в лоб" - идем по массиву по-порядку и прежде чем вывести его значение убеждаемся в его наличии. Для примера попробуйте заменить строку "$list = [10, 20, 30];" на, например "$list = [2 => 10, 5 => 20, 7 => 30];", после чего данные в массиве будут расположены не по-порядку и рассмотренный сейчас пример прохода по массиву с ним уже не справится (будут ошибки о том, что указанный индекс массива не существует). Но что же делать с ассоциативным массивом, у которого строковые индексы, ведь их угадать уже не получится! Специально для таких случаев разработчики PHP дали ему цикл foreach(), синтаксис которого таков:

foreach(<array> as $key => $value)

А его работу рассмотрим на простеньком примере. Допустим, мы храним
Навигация (1/2): далее >
Статья была полезной?
· Да, наконец-то разобрался с темой 0% (0)
· Да, узнал немного нового 100% (1)
· Да, но не узнал ничего нового 0% (0)
· Нет 0% (0)
· Нет, объясняется не достаточно понятно 0% (0)
· Нет, написано плохо 0% (0)
· Нет, написано очень плохо 0% (0)
· "Сколько сейчас градусов ниже нуля?" 0% (0)
Опрос закрыт.

Комментарии (0)

Показать комментарий
Скрыть комментарий
Для добавления комментариев необходимо авторизоваться
Последние
Легенды Крови
Удивительный мир фантазий, сражений и тайн... Битв
Тема: Светлая | Тёмная
Версия: Mobile | Lite | Touch | Доступно в Google Play