Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Всё_о_Паскале.doc
Скачиваний:
7
Добавлен:
20.11.2018
Размер:
4.54 Mб
Скачать

16.2 Оператор безусловного перехода

С задачей досрочного выхода из кратных циклов свяжем изучение ранее неиспользуемого нами оператора безусловного перехода. Его общий вид следующий:

Goto Метка;

Здесь Метка – специальным образом указанное место в программе. Действие Goto очень просто: независимо от каких-либо условий он осуществляет передачу управления на оператор, следующий за меткой (отсюда название оператора). Каждая метка имеет вид

m:

где m – имя, построенное по обычным правилам или целочисленная константа от 0 до 9999 включительно. Метку недостаточно поставить перед нужным оператором – ее нужно еще и объявить в разделе описаний оператором

label m;

Можно объявить и несколько меток сразу, разделив их имена запятыми. Принято располагать оператор описания меток до оператора var. Таким образом, метки и оператор goto позволяют решить задачу быстрого непосредственного перехода к нужному месту в программе:

Label 10,20;

Var i,j:integer;

Begin

Write ('Введите значение I (i>2)');

Readln (i);

If i<3 then goto 10;

j:=2;

20:

if i mod j = 0 then write (j,' ');

j:=j+1;

if j<i then goto 20;

10:

End.

Эта несложная программа позволяет пользователю ввести число i, большее двух, после чего печатает все числа от 2 до i-1, на которые i делится без остатка (проверка остатка от деления i на j выполнена операцией mod). В случае ввода пользователем недопустимого значения i (меньшего трех) происходит переход на метку 10:, расположенную перед закрывающим оператором end. – таким образом, программа сразу же завершается. Метка 20: позволяет организовать цикл без использования операторов while, repeat или for. Действительно, перед меткой 20: переменная j получает начальное значение 2, затем, если i делится на j без остатка, значение j выводится на экран, затем увеличивается на единицу и, если значение i не достигнуто, совершается переход на метку 20:, проверяющую уже новое значение j. Однако, и той, и другой цели можно было достигнуть без использования goto, применяя только операторы цикла и break;.

С правомерностью использования простого оператора goto связаны сложные и многолетние споры. Несомненно, что программу всегда можно написать, не прибегая к goto (иногда структурное программирование называют даже "программированием без goto"), не вызывает сомнения также, что использование меток и goto нарушает и усложняет восприятие структуры программы человеком. Однако автору представляется чрезмерным требование изгнать goto совсем – в ряде ситуаций он просто удобнее, чем другие средства. Представим, что нам нужно досрочно выйти из двойного (или вообще кратного) цикла. Оператор break;, расположенный во внутреннем цикле, прервет его выполнение, но выполнение внешнего цикла продолжится со следующего шага. Без goto выйти "из всех циклов сразу" можно разве что с применением специальных переменных-флагов:

Var flag:boolean; {описали переменную-флаг}

. . .

Flag:=false; {до двойного цикла флаг установлен в "ложь"}

While true do begin {начали внешний цикл}

While true do begin {начали внутренний цикл}

. . .

If Условие then begin

{случилось что-то, требующее выхода из обоих циклов сразу!}

Flag:=true; {ставим флаг, сообщая внешнему циклу, что

требуется завершение}

Break; {выход из внутреннего цикла}

End;

End;

If Flag=true then break;

{внешний цикл на каждом шаге должен отслеживать состояние флага!}

End;

Если цикл тройной – при таком подходе понадобится уже два флага, и так далее. Альтернативный путь – установить максимальные значения управляющих переменных внешних циклов – также не соответствует канонам структурного программирования. С goto все выглядит проще и естественней:

Label go1;

. . .

While true do begin {начали внешний цикл}

While true do begin {начали внутренний цикл}

. . .

If Условие then goto go1; {вышли из двух циклов сразу!}

End;

End;

Go1:

. . .

Второй аспект возможного использования goto связан с написанием сложных подпрограмм (см. главу 18), способных завершаться в различные моменты своего выполнения. Зачастую удобнее, чтоб подпрограмма имела всего одну "точку выхода" – свой последний оператор, а досрочный выход осуществляется установкой возвращаемого значения и переходом на последний оператор с помощью goto.

Ограничения на использование goto следующие: метка должна находиться в том же блоке программы, что и оператор goto. Таким образом, нельзя перейти из одной части сложной программы (такой, как процедура или функция, изучаемые в главе 18) в другую. Несомненно, что эти ограничения введены разработчиками, чтоб не усложнять и без того сложное восприятие программ, злоупотребляющих данным оператором.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]