13.15. Конструкция for в PHP
При использовании оператора while цикл обычно выглядит следующим образом: Начальное выражение:
while (условие)
{
// последовательность операторов
выражение_управления_циклом;
}
Последовательность операторов в теле цикла должна быть выполнена фиксированное число раз. Но в РНР, как и в С, предусмотрена конструкция, позволяющая делать то же самое более компактно — цикл for. Ниже приведен цикл for, эквивалентный предыдущему циклу while:
for (начальное_выражение; условие; выражение_управления_циклом) {
// последовательность операторов.
}
Первое выражение начальное_выражение безусловно выполняется. В начале каждой итерации (проход цикла) вычисляется условие. Если оно равно true, то цикл продолжается и выполняется вложенный оператор или операторы. Если оно равно false, то цикл заканчивается. В конце каждой итерации исполняется жение_управления_циклом. Каждое из этих выражений может быть пустым. Если условие пусто, то цикл продолжается бесконечно (РНР по умолчанию считает его равным true, как и в языке С). Это не так бесполезно, как может показаться, так как зачастую требуется закончить выполнение используя оператор break
в сочетании с логическим условием вместо использования логического выражения в for. Если внутри цикла встречается оператор break, цикл прекращает выполнение итераций и управление передается следующей за циклом команде. Если встречается оператор continue, управление передается на начало следующего цикла.
Схематично выполнение цикла можно представить так: При выполнении цикла for происходит следующее:
1. Выполняется Это происходит только один раз при входе
в цикл.
2. Проверяется условие. Если его значение равно true, то осуществляется переход к третьему пункту. Если же оно ложно, то управление передается оператору, следующему за блоком цикла for. Если это значение изначально было равно
то операторы в теле цикла не выполняются ни разу.
3. Выполняется последовательность операторов.
4. Вычисляется выражение_управления_циклом.
5. Возврат в пункт 2.
Инструкции начальный_оператор, условие И выражение_управления_циклом ДОЛЖНЫ удовлетворять некоторым условиям. Обязательно должна присутствовать точка с запятой, т. е. корректная следующая запись:
for ( ;;) {
// последовательность операторов
}
Это эквивалентно такому циклу:
while(1)
{
// последовательность операторов
}
Обычно начальное_выражение используется для инициализации и объявления переменной управления циклом. Здесь можно вставлять и инициализировать и другие
На рис. 13.5 приведена структурограммациклической конструкции for.
Рис. 13.5. Цикл for
Как несложно догадаться условие чаще всего используется для проверки условия завершения цикла. Как правило, в нем происходит сравнение переменной управления циклом с некоторым значением.
Инструкция обычно используется для приращения счетчика цикла. В данном случае безразлично, использовать ли инкремент в префиксной или же постфиксной форме, поскольку на значение управляющего выражения это никак не влияет.
Рассмотрим следующие примеры. Все они выводят номера с 1 по 10:
Пример 13.1. Конструкция for (вариант 1)
for ($i = 1; $i <= 10; $i++) {
print $i;
}
Пример 13.2. Конструкция for (вариант 2)
for ($i = 1;;$i++) {
if ($i > 10) {
break;
}
print $i;
}
Пример 13.3. Конструкция for (вариант 3)
$i = 1; for (;;) {
if ($i > 10) {
break;
}
print $i;
$i++;
}
Пример 13.4. Конструкция for (вариант 4)
for ($i = 1; $i <= 10; print $i, $i++);
Конечно, первый вариант кажется лучшим, но возможность использования пустых выражений в цикле for зачастую является полезной.
РНР также поддерживает альтернативный синтаксис for:
for (expr1; ехрr2; ехрr3) : выражение; ...; endfor;
ВНИМАНИЕ
Другие языки программирования используют оператор foreach для того, чтобы обрабатывать массивы или списки. РНР использует для этого оператор while и функции, list() и each(). Для примера смотрите документацию по этим функциям (на сайте www.php.net).
Приведем пример, в котором будет представлена программа сортировки случайных целых чисел. Алгоритм сортировки сравнивает элементы, находящиеся в массиве далеко друг от друга, и при необходимости меняет их местами. Промежуток между сравниваемыми элементами постепенно уменьшается до единицы — тогда сравниваются соседние элементы и так при необходимости меняются местами.
Таким образом, происходит сортировка массива:
<?
$size = 10;
for ($a =0; $a < $size; $a++) $aray[$a] = rand();
print "Выводим рандомные значения массива: <br>n";
for ($a = 0; $a < $size; $a++)
print " $aray[$a] ";
for ($g = $size/2; $g>0; $g /=2)
for($a = $g; $a < $size; $a++) // средний цикл
// внутренний цикл:
for ($j = $a-$g; ($j >= 0) && ($aray[$j] > $array[$j+'$g]); $j -= $g) {
$temp = $array[$j];
$aray[$j] = $aray[$j + $g];
$aray[$j + $g] = $temp;
}
print "<br> Сортированные значения массива: <br>n";
for ($a = 0; $a < $size; $a++)
print" $aray[$a] ";
?>
В результате выполнения программы на экран будетвыведено: Выводим рандомные значения массива:
41 18467 6334 26500 19169 15724 11478 29358 26962 24464
Сортированные значения массива:
41 6334 11478 15724 18467 19169 24464 26500 26962 29358
Случайные числа, генерируемые вашим компьютером, могут отличаться от приведенных.
Сначала массив заполняется случайными которые генерирует компьютер. Функция rand используется для генерации случайных чисел. Алгоритм сортировки состоит из трех вложенных циклов Внешний цикл устанавливает начальный интервал между сравниваемыми элементами в половину размера массива. При каждой итерации интервал уменьшается в два раза. Внешний цикл завершается тогда, когда размер интервала достигнет нуля. Можетли случиться так, что это условие не будет удовлетворено и цикл будет ли переменная $g (интервал) «застрять» в промежутке между 1 и 2? Нет. В конце концов значение $g достигнет 1, а при следующем делении на 2 уменьшится до 0,5, что при отбрасывании целой части (так как $g — целое) даст нуль.
Средний цикл сравнивает элементы массива, разделенные интервалом $g. Переменной цикла $а изначально присваивается значение $g. На каждом шаге цикла ее значение увеличивается на единицу, таким образом, условие окончания цикла всегдадостижимо.
Внутренний цикл меняет местами элементы, если они не расположены по порядку. Переменной цикла $j изначально присваивается нулевое значение при проходе среднего цикла. При второй итерации оно становится равным 1 и т. д. Переменная $j уменьшается на величину $g при каждом переходе внутреннего цикла. Условие цикла состоит из двух выражений, причем для продолжения цикла необходимо, чтобы оба они были истинными. Легко заметить, что первое условие в конечном итоге прекратит выполнение цикла, поскольку переменная цикла примет нулевое значение.