Обратная форма оператора for
Запись обратной формы этого оператора имеет вид:
for <идентификатор переменной порядкового типа> :=
n1 downto n2 do <оператор>;
nl — начальное (большее) значение соответствующего типа; n2 – конечное (меньшее) значение соответствующего типа. Если n1 < n2, то оператор цикла вообще не выполняется.
Примеры. Эти примеры повторяют вышеприведённые примеры, но счётчик цикла изменяется в обратном направлении.
1)
for i:= 100 downto 1 do S:= S + i*i;
2)
for c:= 'Z’ downto 'A' do Writeln(ord(c), ' - ', c) ;
3)
for t:= 400 downto 300 do if (t mod 3) = 0 then Writeln(t);
Как вы заметили, в теле цикла может выполняться только один оператор, который записан непосредственно за структурой for … do. Поэтому, если возникает необходимость, мы можем воспользоваться составным оператором и объединить в теле цикла несколько операторов.
Примеры:
1)
for i: = 1 to 100 do
begin
Writeln(i , ‘)’ );
S:= S + i*i ;
Writeln(S);
end;
2)
for h:= 'F’ to 'X’ do
begin
readln(b, c);
1: = chr(ord(b) - ord(h));
m: = m + chr(ord(c) + ord(h));
writeln (1, m);
end;
Как уже было сказано, счетчиком цикла могут быть переменные любого порядкового типа, даже если это тип пользователя.
Пример:
program р9;
type
Month = (Jan, Feb, Mar, Apr, May, Jun,
Jul, Aug, Sep, Oct, Nov);
var
i: Month;
z: integer;
begin
z : = 0 ;
for i: = Jan to Sep do z: = z + Ord(i)*32;
Writeln(z);
end.
Советы для начинающих
1. Постарайтесь не изменять счетчик цикла в самом цикле. Если хорошо подумаете, то поймете, что в этом нет необходимости, а последствия этого могут оказаться непредсказуемыми.
2. В Паскале нет понятия - шаг цикла (step), вещественный тип не может быть типом счетчика цикла, так как не является перечислимым, но при возникшей необходимости в цикле можно воспользоваться любой вещественной переменной. Для этого на каждой итерации необходимо изменять ее на определенное вещественное значение - шаг.
3. Перед использованием цикла постарайтесь точно понять, «почувствовать» как он работает, что происходит со счетчиком, сколько раз он выполняется, как изменяются переменные в выражениях типа S: = S +..., Р:= Р *. . . и т. п. Их корректность зависит от построения выражения и начальных значений переменных.
Например:
р: = 0;
for i: = 2 to n do p: = p* i;
Стандартная ошибка. В этом примере незадачливый, начинающий программист попытался решить задачу нахождения факториала, а получил ноль.
Задача. Табулировать функцию f(x) на отрезке [а,b] с шагом h.
program p10;
var
a, b, h, x, y: Real;
i, n: integer;
begin
Writeln('введите начало и конец отрезка’);
Read(a, b);
Writeln('введите шаг');
Read(h);
х:= а; {начальное значение переменной х}
n:=round((b-a)/h); {количество полных интервалов}
for i:= 1 to n do
begin
y:= sin(x); { находим значение функции,
для текущего значения аргумента}
Writeln(i, ' х= ' , х, ' у= ' , у) ; { выводим на экран
номер шага, значение аргумента и значение функции}
x:=x+h; {увеличиваем аргумент на значение
шага}
end;
end.
Задача. Вычислить выражение .
program p11;
var
S, f: real;
i, n: integer;
begin
Write('Введите n: ’);
Read(n); {Ввод значения переменной n}
f: = 1;
S: = 0; {начальное значение переменных f и S }
for i: = 1 to n do
begin
f: = f*2;
S:= S + sin(i)/f;
end;
Writeln(' S= ', S: 6: 4) ;
end.
Задача. Вычислить выражение
,
где n, а и b вводятся с клавиатуры.
program p12;
var
a, b, P, k, 1: real;
i, n: integer;
begin
Write('Введите значения a, b и n: ');
Readln (a, b, n);
k:= 1; {начальное значение переменных k,1 и Р}
1:= 1;
P:= 1;
for i:= 1 to n do
begin
k:= k * a;
1:= 1 * b;
P:= P * (sin(k) + cos(l));
end;
Writeln(‘ P= ', P: 6: 4);
end.
Часто возникает необходимость организации вложенных циклов, действие которых можно понять при анализе работы следующей программы:
program р13;
var
i, j : integer;
begin
for i:= 1 to 5 do
for j:= 1 to 5 do writeln ('i= ', i, ' j= ', j); end.
Программа выводит на экран всевозможные пары значений целых чисел до пяти.
i=1 j=1
i=l j=2
i=l j=3
i=l j= 4
i=l j= 5
………
………
………
i=5 j= 2
i=5 j= 3
i=5 j= 4
i=5 j= 5
Каждая строка, выводимая на экран, соответствует одному выполнению тела цикла.
Цикл типа While
Этот цикл используется, если известно условие прекращения цикла, но неизвестно количество итераций.
While <выражение типа Boolean> do <оператор>;
В данном случае <выражение типа Воо1еап> - это условие продолжения цикла (пока условие - истинно, тело цикла выполняется).
Если условие принимает с самого начала значение false, то тело цикла вообще не выполняется.
Конструкция цикла предусмотрена на случай того, что телом является только один оператор, который непосредственно следует за структурой While... do, а для включения в тело цикла нескольких операторов необходимо объединить их в один составной.
Примеры:
1)
While x < у do х: = х - 1 ;
2)
while (a < m) or (b < n) do
begin
a : = a - t ;
b : = b - z ;
end;
При организации цикла While может возникнуть ситуация "зацикливания". Чтобы этого не произошло, по крайней мере, один из повторяемых в теле цикла операторов должен влиять на значение условия прекращения цикла, иначе он будет выполнятся бесконечно.
Примеры:
1)
While true do Writeln('2=2') ;
Данный цикл будет выполнятся бесконечно, так как в теле цикла нет оператора, который бы мог изменить условие продолжения цикла.
2)
while (a < 100) or (a > 100) or (a = 100) do Writeln(a);
В этом цикле условие его продолжения будет всегда выполняться (а – переменная целого типа), а в теле цикла нет оператора влияющего на условие его продолжения. Следовательно цикл будет продолжаться бесконечно.
Задача. Используя алгоритм Евклида, найти НОД (наибольший общий делитель) двух чисел.
Алгоритм Евклида:
1) пока переменные неравны, заменить большее значение на разность большего и меньшего;
2) выбрать любое значение в качестве результата.
program p15;
var
а, b, х, у: integer;
begin
Write('Введите а и b: ');
Readln (a, b);
х := а; {запоминаем начальные значения а и b}
у:=b;
While a <> b do
if a > b then a:= a - b else b:= b – a;
Writeln (‘ HOД( ‘, x, ', ' , y, ') = ' , a);
end.