учебник по паскалю. Программа 5 Алгоритм 5 Свойства алгоритма 6 Формы записи алгоритма 6
Скачать 2.21 Mb.
|
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 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) в другую. Несомненно, что эти ограничения введены разработчиками, чтоб не усложнять и без того сложное восприятие программ, злоупотребляющих данным оператором. 3> |