Теория
Сегодня мы поговорим о циклах. Что это такое? Давайте представим, что вам необходимо вывести на экран слово ПРИВЕТ! двадцать раз. Писать: writeLn ('ПРИВЕТ'); 20 раз !!! А если нужно сто раз? А если заранее неизвестное число раз?? Как быть? Вот тут и нужны циклы.
Цикл - кусок кода, который повторяется определённое число раз (бесконость - это тоже определённое число раз!).
Цикл FOR
Этот цикл наиболее часто используется в программах ввиду его чрезвычайной удобности. Итак знакомтесь, цикл for!
Давайте рассмотрим его использованние на примере с выводом слова привет на экран. Да давайте оговоримся, что будем опускать стандартные куски программы типа Program, var, begin, end. И ещё одно соглашение об именах переменных: обычно именами i и j дают переменным целого типа и их объявление мы тоже будем опускать. Итак пример:
for i := 1 to 20 do
writeLn ('Привет!');
Цикл записывается так for переменная_цикла := начальное_значение to конечное_значение do операторы;
В нашем примере мы взяли в качестве переменной цикла взята переменная i, начальное значение 1, конечное - 20. Что это значит? А это значит, что цикл будет выполняться для i = 1, 2, 3, 4, 5 ... 19, 20. Т.е. 20 раз. Каждый раз мы прибавляем к i еденицу. При этом начальное и конечное значение переменной цикла может задаваться численным выражением (например for i := 1 to 3*65 do ....) или выражением с переменной (например for i := X + Y to X * Y / Z + 45 *j do ....). При этом эти значения вычисляются компилятором один раз перед выполнением цикла. Например, результат такой программы:
Program Test;
var
i : integer;
x : integer;
begin
x := 10;
for i := 0 to х do
begin
writeLn (i, ' ', x);
x := x + 2
end
end.
Будет таким :
0 10
1 12
2 14
3 16
4 18
5 20
6 22
7 24
8 26
9 28
10 30 |
Как видите предел i не поменялся, хотя х мы меняем! Использую цикл for нужно соблюдать следующее правило: не нужно менять переменную цикла (т.е. ту переменную, по которой идёт цикл, у нас это была i) внутри него.
Есть ещё один альтернативный вариант цикла for, который используется, когда считать нужно не "снизу вверх" а "сверху вниз". Например мы хотим изменять i не от 1 до 20, а наоборот от 20 до 1. Тогда наш цикл примет вид:
for i := 20 downto 1 do
writeLn ('Привет!');
Теперь i = 20, 19, ... 2, 1. А так всё аннологично. Основное неудобство состоит в том, что мы не можем задавать закон изменения переменной цикла. Однако и это не так страшно, как кажется на первый взгляд.
Цикл WHILE
Цикл номер два: while! Этот цикл называется циклом с предусловием. Записывается он так:
while условие do оператор;
Такой цикл выполняется пока условие истинно. И прекращается в противном случае. Например такой цикл:
while 1 do
writeLn ('Привет!');
Приведёт к "зависанию" компьютера, т.к. выражение 1 всегда истинно (не могут же быть числа ложными). выйдти из этого цикла можно нажатием клавиши Ctrl+Break (Ctrl+C) - стандартный выход из ДОС программ. Проверка истистинности условия проводится как и в операторе if.
Давайте покажем, как оператором While можно заменить for:
i := 1;
x := 10;
while i <= x do
begin
writeLn (i, ' ', x);
x := x + 1;
i := i + 1
end;
Попробуйте этот код... ну как эффект не тот? :) Давайте разберёмся в чём дело. А вся проблемма в том, что условие (максимальное значение) для цикла for считается зарание один раз заранее! А у нас оно всё время меняется. Ок. Теперь посмотрите результат программы: она останавливается при i = 32 757. Давайте посмотрим ещё один вариант:
i := 1;
x := 10;
while i <> x do
begin
writeLn (i, ' ', x);
x := x + 1;
i := i + 1
end;
Запустите и подождите немного.... СТОП! А откуда там отрицательные числа?? Ведь мы прибавляем каждый раз по 1 и 1, т.е. i и х растут ???
Давайте разберёмся по подробнее. Что из себя представляет числовая прямая? Это окружность максимального радиуса, т.е. радиуса бесконечность. Такая окружность вырождается в прямую. Однако для целых чисел (типа integer) эта "бесконечность" известна - 32767 (помните выпуск Типы данных?). Счечик i можно представить, как точку, которая движется по этой окружности. Когда i доходит до максимума, то она становится отрицательной, т.е. -32767!!
А помните предыдущий пример, где всё останавливалось при x = 32 767. Почему так вышло? Прибавляя к х = 32767 один что мы получаем: x + 1 = -32767 !!!! А условие цикла у нас стоит i <= x т.е. когда х = 32 767 i = 32 757, далее х + 1 = -32 767 i + 1 = 32 758 т.е. условие i <= x не выполняется! И поэтому мы выходим из цикла!
Поэтому аккуратнее с максимальным значение integer, оно не такое большое, как может показаться!
Теперь напишем нормальный вариант цикла for через цикл while:
i := 1;
x := 10;
Temp := x;
while i <= Temp do
begin
writeLn (i, ' ', x);
x := x + 1;
i := i + 1
end;
Здесь мы заранее посчиталь верхнюю границу цикла в переменную temp и тем самым всё работает правильно.
Ну и напоследок...
Ну вот мы подошли к последнему циклу. Он называется цикл с постусловием, цикл: repeat-until ! Этот цикл в общем и целом анологичен while, но есть два отличия. Вот как он записывается:
repeat оператор until условие;
Итак его отличия от while:
- самое важное: проверка условия совершается после выполнения оператора. Таким образом этот цикл обязательно выполнится хотя бы один раз. В то время как while, может и не выполняться ни разу.
- не самое важное, но очень нужно запомнить, что критерием прекращения цикла является тот случай, когда условие истинно, а если оно ложно, то цикл продолжится! В то время как в while абсолютно противоположная ситуация.
Давайте же рассмотрим какой-нить пример:
i := 10;
repeat
writeLn (i);
i := i - 1
until i = 0;
Этот цикл выполняется пока i не равно нулю. Т.е. для значений i = 10, 9, 8 ..... 2, 1. Обратите внимание, что мы не используем операторы begin-end т.к. этот цикл доспукает использовать в своём теле сколько хочешь операторов в отличие от while и for.
Вот написал и вспомнил о том, что не сказал, что такое тело цикла :( Вот дырявая башка! Итак тело цикла - это та последовательность операторов, которая выполниется. Т.е. например все операторы между repeat и until - это и есть тело цикла.
|