Смекни!
smekni.com

Object Pascal (стр. 8 из 16)

13.4. Оператор цикла For – Do

Синтаксис оператора имеет две разновидности:

For счетчик цикла:=нач.знач. To конеч.знач. Do оператор

For счетчик цикла:=нач.знач. Downto конеч.знач. Do оператор

Здесь конструкция For .. Do называется заголовком цикла, оператор – телом цикла.

Для циклов должны соблюдаться следующие правила и ограничения:

начальное и конечное значения счетчика цикла должны быть одинаковых простых типов, кроме Real;

в теле цикла счетчик не должен менять значение;

вход в цикл минуя заголовок запрещен;

для первой разновидности начальное значение не должно быть больше конечного;

для второй разновидности начальное значение не должно быть меньше конечного.

Первая разновидность оператора цикла For работает следующим образом. Сначала счетчик цикла принимает нач.знач. и выполняется оператор, расположенный вслед за словом Do. Затем значение счетчика будет увеличено на шаг счетчика 1 и вновь будет выполнен оператор и т. д., пока счетчик не переберет все значения от нач.знач. до конеч.знач.

Пример.

s:= 0;

For i:=1 to 44 do s:= s + z[i];

В результате в переменной s будет накоплена сумма первых 44 элементов массива z.

Другая разновидность оператора For отличается лишь отрицательным шагом –1 счетчика.

Пример.

s:= 0;

For i:=44 Downto 1 do s:= s + z[i];

Будет получен тот же результат.

13.5. Оператор цикла While – Do

Синтаксис оператора:

While логическое выражение Do оператор;

Цикл выполняет оператор, расположенный вслед за словом Do до тех пор, пока истинно логическое выражение, расположенное за словом While ("выполняй, пока истинно").

Пример.

x:= 0;

i:=0;

While (x < 101.667) do

Begin

Inc (i);

X:= X + 5.617;

Y[i]:= Func (i + 6, 9 * i, X);

End;

В этом примере цикл будет выполняться до тех пор, пока не выполнится условие x < 101.667. В теле цикла переменная X с каждым шагом цикла увеличивает свое значение на 5.617 так, что на определенном шаге условие x < 101.667 впервые не будет выполнено. В этот момент без входа в тело цикл закончит работу.

13.6. Оператор цикла Repeat – Until

Синтаксис оператора:

Repeat

Оператор1;

Оператор2;

ОператорN;

Until логическое выражение;

Цикл работает, пока логическое выражение ложно ("повторяй, пока не выполнится").

Пример.

s:= 0;

i:=0;

Repeat

Inc (i);

s:= s + z[i];

Until (i = 44);

В этом примере цикл будет выполняться до тех пор, пока не выполнится условие i = 44. Результат будет тот же, что в примере для For-цикла.

13.7. Операторы Break и Continue

Оператор Break может быть размещен в теле цикла. При его выполнении цикл прекращает работу и считается выполненным.

Пример.

s:= 0;

i:=0;

Repeat

Inc (i);

s:= s + z[i];

if (s > 14) then Break;

Until (i = 44);

В этом примере цикл будет выполняться до тех пор, пока не выполнится условие i = 44 или если в операторе if переменная s превысит значение 14.

Оператор Continue также может быть размещен в теле цикла. При его выполнении управление независимо от того, где он расположен, сразу передается в начало цикла для выполнения следующего шага.

Пример.

s:= 0;

i:=0;

Repeat

Inc (i);

s:= s + z[i];

if (s > 20) then Continue;

if (s > 14) then Break;

Until (i = 44);

В этом примере если в первом операторе if выполнится условие s > 20, то сработает оператор Continue. Он сразу передаст управление на первый оператор в теле цикла – Inc (i), предотвратив тем самым выполнение ниже-следующих операторов – второго if и Until.

13.8. Вложенные циклы

В теле оператора цикла могут быть размещены другие операторы цикла. Такие структуры называются вложенными циклами. Язык допускает любую глубину вложенности циклов. При использовании вложенных циклов необходимо иметь в виду следующее:

все вложенные циклы For – Do должны иметь различные счетчики (иначе это противоречило бы требованию на запрет изменения значения счетчика внутри цикла);

нет никаких ограничений на досрочный выход из внутреннего цикла наружу;

недопустим вход во внутренний цикл For – Do, минуя его заголовок, что соответствует общему требованию о корректном входе в цикл.

Вложенные циклы используются в ситуациях, когда на каждом шаге наружного цикла необходимо полностью выполнить внутренний цикл.

Пример.

Const

n = 15;

m = 24;

Var

i,j: Byte;

R,Tau,s: Real;

z: array[1..n, 1..m] of Real;

{заполнение массива z с использованием вложенных циклов}

Tau:= Pi/m;

For i:=1 to n do begin

R:=4.0*Pi*Sin(i*Tau); {первый оператор в теле цикла по i}

For j:=1 to m do z[i, j] := R+j; {второй оператор в теле цикла по i}

end {i};

{вычисление суммы положительных элементов массива z с использованием вложенных циклов }

s:=0;

For i:=1 to n do

For j:=1 to m do

if ( z[i, j] > 0) then s:= s + z [i, j];

Приведенный пример содержит две структуры вложенных циклов. Первая структура предназначена для заполнения элементов двумерного массива z с помощью математической формулы

Object Pascal

Наружный цикл со счетчиком i в теле цикла содержит два оператора – оператор присваивания (вычисление значения вспомогательной переменной R с целью сокращения времени вычислений) и оператор внутреннего цикла со счетчиком j. Поскольку наружный цикл в своем теле содержит несколько операторов, то они заключены в операторные скобки begin … end.

Эта структура работает следующим образом. После входа в наружный цикл переменная i (счетчик этого цикла) примет значение 1. Далее будет вычислено значение переменной R при i = 1. После этого будет выполнен внутренний цикл со счетчиком j, где j на каждом шаге будет последовательно принимать значения 1, 2, 3, … m (i при этом остается неизменным и равным 1). В результате будут вычислены элементы z11, z12,,z1m первой строки массива. Затем будет выполнен возврат к заголовку наружного цикла, где значение счетчика i будет увеличено на 1 (т. е. i станет равно 2) и вновь будет выполнены операторы, расположенные в его теле. В результате будут определены элементы z21,z22,,z2m второй строки массива и т.д.

Вторая структура вложенных циклов предназначена для вычисления суммы положительных элементов массива z. Для этого сначала переменной s будет присвоено значение 0, а затем во вложенных циклах будет накоплена требуемая сумма в ячейку s.

13.9. Оператор записи With

В ранних версиях языка оператор использовался для более удобного доступа к полям записи.

Пример:

Var

Student : Record

Fam: String[30];

Name: String[20];

Age: Word;

End;

Student.Fam:= 'Колокольников';

Student.Name:= 'Павел';

S:=Student.Fam + ' '+Student.Name;

{предыдущих три оператора эквивалентны следующим}

With Student do

Begin

Fam:= 'Колокольников';

Name:= 'Павел';

S:= Fam + ' '+ Name;

End;

13.10. Оператор Try – Except – End

Это новейшее средство языка. Блок Try – Except – End используется для предотвращения исключительных ситуаций (ИС), которые могут возникнуть при выполнении программы. К их числу относятся сбои в работе аппаратуры, ошибки вычислений (например деление на нуль), попытки присвоить значение, выходящее за пределы типа и т. д.

Синтаксис:

Try

{операторы, способные генерировать ИС}

Except

{операторы, обрабатывающие генерированные ИС}

end;

Блок Try – Except – End работает следующим образом. Выполнение начинается с операторов, расположенных в блоке Try – Except. Если в каком-либо операторе возникает ИС, то она подавляется и затем выполняются все операторы, расположенные в блоке Except – End. В результате предотвращается аварийное прерывание программы. Использование блока Try – Except – End открывает возможность программного контроля за ИС.

Пример.

i:= 0;

n:= 8;

Try

i:= n div i; {Деление на нуль. Оператор генерирует ИС}

n:= i + 9;

Except

ShowMessage('Ошибка. Деление на нуль в операторе i := n / i');

End;

Результатом выполнения блока операторов будет появление на экране формы с сообщением "Ошибка. Деление на нуль в операторе i := n / i", после чего программа продолжит работу с оператора, следующего за словом End, а не с оператора n := i + 9.

Если бы оператор i := n div i не был защищен блоком Try – Except – End, то возникшая при его выполнении ИС привела бы к нежелательному аварийному завершению программы.

13.11. Оператор On – End

При возникновении ИС язык позволяет не только предотвратить прерывание программы, но и определить, какого именно вида была ИС. Для этого в блоке Except – End можно использовать оператор On –Do.

Пример

i:= 0; n:= 8;

Try

i:= n div i; {Деление на нуль. Оператор генерирует ИС}

n:= i + 9;

Except

On Ex: EdivByZero do ShowMessage('Деление на нуль');

End;

В этом примере сообщение о возникновении ИС будет выдано только в случае, когда ИС будет только деление на нуль (EdivByZero). Во всех остальных случаях ИС будет предотвращена, однако никакого сообщения о ее возникновении выдано не будет. Объявленная в блоке Except – End переменная Ex может быть любым именем (здесь Ex используется только для примера).

13.12. Оператор Try – Finally – End

Блок Try – Finally – End также используется для предотвращения ИС, которые могут возникнуть при выполнении программы. В отличие от блока Try – Except – End блок Try – Finally – End используется для освобождения ресурсов памяти, закрытия файлов и пр. в случае возникновения ИС.

Синтаксис:

Try

{операторы, способные генерировать ИС}

Finally

{операторы освобождения ресурсов памяти }

end;

Блок Try – Finally – End работает следующим образом. Выполнение начинается с операторов блока Try – Finally, которые в правильно написанной программе должны содержать операторы выделения ресурсов памяти. Если в каком-либо операторе возникает ИС, то управление сразу передается к операторам блока Finally – End, где производится освобождение памяти, закрытие файлов и пр. В результате, с одной стороны, предотвращается аварийное прерывание программы и, во вторых, корректно освобождается ранее зарезервированная память, выполняется ряд других необходимых операций.