Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
основы программирования на Паскале.doc
Скачиваний:
255
Добавлен:
25.03.2016
Размер:
4.34 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) в другую. Несомненно, что эти ограничения введены разработчиками, чтоб не усложнять и без того сложное восприятие программ, злоупотребляющих данным оператором.