В практике программирования циклы - повторяющиеся выполнения однотипных действий - играют очень важную роль. Существует три стандартных способа организации циклических действий:
1. оператор цикла с параметром (цикл FOR)
2. оператор цикла с предусловием (цикл WHILE)
3. оператор цикла с постусловием (цикл REPEAT)
1. Оператор цикла FOR
Оператор цикла FOR организует выполнение одного оператора или группы операторов заранее известное число раз. Достигается это с помощью управляющей переменной, называемой параметром цикла. Следующий простой пример иллюстрирует использование цикла с параметром:
for I:=1 to 10 do writeln('Привет!');
В данном примере задано десятикратное повторение оператора вывода. Переменная I является параметром цикла и последовательно принимает значения 1, 2, 3,..., 10, т.е. параметр цикла автоматически принимает последовательно все целые значения, начиная от начального значения (в примере - от 1) до конечного значения (в примере - до 10). В результате выполнения данного оператора на экран дисплея будет выведено десять строчек со словом 'Привет!'.
|
|
Существует другой вариант оператора цикла FOR. Рассмотрим его на примере:
forI:=10 downto 1 dowriteln(I);
В данном примере вместо ключевого слова TO используется ключевое слово DOWNTO. И это будет означать, что параметр цикла будет уменьшаться на 1 при каждом новом выполнении тела цикла.
Т.е. переменная I будет принимать последовательно значения 10, 9, 8,..., 1.
В общем виде оператор цикла с параметром имеет два варианта записи.
Вариант 1:
For <имя>:=<выражение1> TO <выражение2> DO <оператор>
Вариант 2:
For <имя>:=<выражение1> DOWNTO <выражение2> DO <оператор>
В этих операторах:
<имя> - параметр цикла, являющийся переменной порядкового
типа (перечислимого или ограниченного); <выражение1> - выражение, определяющее начальное значение
параметра;
<выражение2> - выражение, определяющее конечное значение
параметра;
<оператор> - тело цикла (выполняемый оператор или группа
операторов, оформленных как составной оператор: begin... end).
Таким образом, оператор цикла с параметром определяет:
- диапазон изменения значений управляющей переменной и, одновременно, число повторений оператора, содержащего тело цикла;
- направление изменения значения переменной (возрастание или убывание);
- собственно действия, выполняемые на каждом шаге (тело цикла).
Цикл действует таким образом.
Шаг 1. Сначала вычисляются и запоминаются начальное (<выражение1>) и конечное значение (<выражение2>) параметра цикла.
Шаг 2. Параметру цикла <имя> присваивается начальное значение <выражение2>.
Шаг 3. Значение параметра цикла сравнивается со значением <выражение2>. Если параметр цикла больше конечного значения (в первом варианте оператора), или меньше конечного значения (во втором варианте оператора), то выполнение оператора цикла завершается и управление передается команде, следующей за оператором цикла.
|
|
Шаг 4. Выполняется тело цикла.
Шаг 5. После выполнения тела цикла происходит присваивание параметру цикла следующего значения (большего - в первом варианте записи, меньшего-во втором случае). Переход к шагу 3.
На использование управляющей переменной накладываются следующие ограничения:
1. Управляющая переменная должна быть описана в текущем блоке.
2. Управляющая переменная должна иметь дискретный тип.
3. Начальные и конечные значения диапазона должны иметь тип, совместимый с типом управляющей переменной.
4. В теле цикла запрещается явное изменение значения управляющей переменной (например, оператором присваивания).
5. После завершения оператора цикла значение управляющей переменной становится неопределенным.
Рассмотрим примеры использования цикла FOR.
Предположим, что у нас есть следующее описание переменных:
Var
I:integer;
C:char;
B:boolean;
Col=(Red,Yellow,Green,Blue,White);
Тогда будут правильными с синтаксической точки зрения следующие конструкции цикла:
а) for I:=-10 to 10 do writeln(I);
б) for I:=10 downto -10 do writeln(I);
в) for C:='a' to 'r' do writeln(C);
г) for b:=False to True do writeln(b);
д) for Col:=Red to White do writeln(ord(Col);
2. Вычисление сумм и произведений.
Ниже приводится пример программы, вычисляющей сумму квадратов первых N целых чисел, SUM=1*1+2*2+...+N*N
Пр.1.
program SUM;
var N,sum,I:integer;
begin - начало тела главной программы
writeln;
writeln('<<< вычисления суммы квадратов первых N чисел >>>');
writeln;
write('N =? ');
readln(N);
sum:=0;
FOR I:=1 TO N DO sum:=sum+I*I;
writeln('сумма квадратов первых ',N,' чисел pавна ',sum);
readln;
end.
Пр.2 Подсчитать произведение Р= 1*2*3*...*N.
program Proizv;
var
P:real;
N,I:integer;
begin - начало тела главной программы
writeln;
writeln('<<< вычисление произведения N чисел >>>');
writeln; write('N =? ');
readln(N);
P:=1;
FOR I:=1 TO N DO
P:=P*I;
writeln('произведение ',N,' чисел pавно ',P);
readln;
end.
В практике программирования достаточно часто возникает потребность использовать вложенные циклы. Примером такого использования вложенных циклов может быть программа, вычисляющая и печатающая таблицу Пифагора:
Пр.3
program PIFAGOR;
var I,J:integer;
begin - начало тела главной программы
writeln('<<< ТАБЛИЦА ПИФАГОРА >>>');
writeln;
for I:=1 to 10 do повертикали
begin
for J:=1 to 10 do погоризонтали
write((I*J):4);
writeln переход на следующую горизонталь
end;
readln
end.
3. Максимумы и минимумы.
Еще одна часто встречающаяся задача - выбрать наибольшее число из вводимой последовательности. Идею алгоритма можно проиллюстрировать на такой ситуации: идет строй юношей, нам нужно определить рост самого высокого из них. Мы устанавливаем планку на высоте роста первого из них, а дальше действуем так: если юноша не проходит под планкой - поднимаем планку на высоту его роста, если же проходит - планка остается на месте. После того, как строй закончился, высота планки соответствует наибольшему росту.
Вот, как это записывается на языке Pascal:
program Pr;
var i,max,a:real;
begin
Write('Введите рост: ');
readln(a); вводим первое число
max:= a; устанавливаем "планку"
for i:=2 to n do начинаем с 2, т.к. первое
число уже обработано
begin
write('Введите рост:');
readln(a); вводим очередное число
if a > max если "не прошел под планкой"
then max:= a; "подняли планку"
end;
max - наибольшее число
ReadLn end.
Если кроме самого числа нас интересует его номер, то нужно в цикле запоминать номер каждого "подозрительного на наибольший" элемента:
readln(a); вводим первое число
max:= a; устанавливаем "планку"
k:= 1; запоминаем номер
for i:=2 to n do начинаем с 2, т.к. первое
число уже обработано
begin
readln(a); вводим очередное число
|
|
if a > max then если "не прошел под планкой"
begin
max:= a; "подняли планку"
k:= i; запомнили номер
end;
max - наибольшее число, k - его номер
4. Цикл с предусловием WHILE
Если какое-то действие или несколько действий необходимо выполнить много раз, но заранее неизвестно сколько раз и это зависит от какого-то условия, то тогда следует воспользоваться циклом с предусловием, имеющим вид:
WHILE <условие> DO <оператор>;
Конструкция читается: пока выполняется условие делать... Условие - это логическое выражение, истинность которого
проверяется в начале каждой итерации.
Оператор, следующий за ключевым словом DO называется телом цикла. На месте тела цикла может быть записан составной оператор BEGIN... END. В этом случае цикл с предусловием будет иметь вид:
WHILE <условие> DO
BEGIN
<операторы>
END;
Перед каждым новым выполнением тела цикла проверяется условие и если оно истинно (TRUE), то выполняется тело цикла, а иначе цикл заканчивается и выполняется команда, следующая за данной алгоритмической конструкцией.
Рассмотрим пример.
Составить программу для вычисления и вывода на печать таблицы значений функции y=a*x*x, x=5,6,...,N
program Function1;
var
y,a:real;
x,N:integer;
begin - начало тела главной программы
writeln;
writeln('<<<Введите N и а >>>');
writeln;
readln(N,a);
x:=5;
while x<N do
begin
y:=a*sqr(x);
Writeln(x,y); x:=x+1
end;
end.
5. Цикл с постусловием REPEAT
Рассмотренный выше цикл с предусловием устроен так,что проверка условия производится до первой итерации (до первого выполнения тела цикла). Иногда это не соответствует логике алгоритма. Например,в тех случаях, когда проверка условия актуальна лишь после завершения предыдущего шага. Тогда нам идеально подходит цикл с постусловием REPEAT.
Оператор цикла REPEAT организует выполнение цикла, состоящего из любого числа операторов, с неизвестным заранее числом повторений. Тело цикла выполняется хотя бы один раз. Выход из цикла осуществляется при истинности (!) некоторого логического выражения.
Общий вид цикла с постусловием:
REPEAT
<оператор1>;
<оператор2>;
|
|
...
<операторN>;
UNTIL <условие>;
Операторы, записанные между ключевыми словами REPEAT и UNTIL, составляют тело цикла. Так как слова RPEAT и UNTIL являются своеобразными операторными скобками, то точку с запятой перед словом UNTIL ставить не нужно. Тело цикла может быть пустым или содержать один или более операторов.
Условие, записанное после ключевого слова UNTIL, проверяется в конце каждой итерации (после выполнения тела цикла). Условие - это логическое значение, переменная или выражение с логическим результатом. Но важно обратить внимание, что оно работает здесь не совсем так, как в цикле WHILE. Если в цикле WHILE подразумевается алгоритм "пока условие истинно, выполнять операторы тела цикла", то цикл REPEAT соответствует алгоритму "выполнять тело цикла, пока не станет истинным условие". Иными словами, если условие является истинным (True), то выполнение цикла завершается. Если условие не выполняется (является ложным - False), то вновь выполняется тело цикла.
Иллюстрацией к вышесказанному может быть конструкция вечного цикла:
REPEAT UNTIL False;
Этот цикл пустой и никогда не прекращающийся. Он хорош только тогда, когда нужно заблокировать программу. Но вообще на совести программиста лежит выбор корректного условия, т.е. такого, которое на каком-то шаге итерации станет False.
Рассмотрим пример программы с использованием цикла REPEAT.
program Function1;
var
y,a:real;
x,N:integer;
begin - начало тела главной программы
writeln;
writeln('<<<Введите N и а >>>');
writeln;
readln(N,a);
x:=5;
repeat
y:=a*sqr(x);
Writeln(x,y); x:=x+1
until x>N;
end.
Пр 2.
program MAX_repeat;
подключениебиблиотеки
varA,B:integer;
begin - началотелаглавнойпрограммы
writeln('<<< НАХОЖДЕНИЕ МАКСИМАЛЬНОГО ИЗ ДВУХ ЦЕЛЫХ ЧИСЕЛ >>>');
writeln;
writeln(' программа закончит работу, если оба числа равны 0');
writeln;
repeat начало цикла
write('Первое число =?'); readln(A);
write('Второечисло =? '); readln(B);
if A=B then writeln('Числаравны')
else
begin
write('Максимальное из двух чисел ');
if A>B then writeln(A)
else writeln(B)
end
until (A=0) and (B=0); конеццикла
end.
Данная программа будет выполняться до тех пор, пока оба введенных числа не станут равны 0. Вообще цикл REPEAT достаточно часто используется с целью многократного повторения выполнения программы с различными данными.