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




Оператор Goto, имеющийся во многих алгоритмических языках, включая и Турбо Паскаль, можно с полным правом назвать «злосчастным». В разгар моды на структурное программирование он подвергся сильным гонениям, ибо было доказано, что можно вообще программировать без него. Из-за того же Goto здорово доставалось Фортрану и раннему Бейсику, большей частью справедливо, так как от пары десятков переходов вдоль и поперек программа не становится более понятной.

Но на практике выбор между чистотой идеи (структурное программирование) и элементарным удобством (использование Goto) был предрешен, и в структурном Паскале мы можем использовать безусловные переходы по программе.

Полный синтаксис оператора перехода — это

Goto Метка; {103}

где метка — описанный в блоке LABEL идентификатор (цифры от 0 до 9999 или собственно идентификатор). Метка может стоять в программе «где угодно» между операторами. При этом каждая метка может появиться только один раз (рис. 6.3):

LABEL m10, m20, StopLabel, 1; VAR i: ShortInt; BEGIN 0001: IF i<10 THEN Goto m10 ELSE Goto m20; ... m10: WriteLn('i меньше 10'); Goto StopLabel; m20: i:= i - 1; ... Goto 1; StopLabel: END.

Рис. 6.3

Метка от оператора должна отделяться символом «:». Если метка обозначается цифрой, то предшествующие нули не являются значащими. Так, на рис. 6.3 метки 1 и 0001 эквивалентны. Обычно метки размещаются у операторов, но могут стоять и у слова END, что означает переход на конец текущего блока BEGIN...END (на рисунке это еще и выход из программы). Перед BEGIN метки не ставятся. Следует избегать переходов (и расстановки меток), передающих управление внутрь составных операторов циклов, да и вообще переходов в составные операторы, вложенные в тот, где выполняется оператор Goto. Другое дело — выход из вложенных операторов во внешние. В таких случаях применение Goto — достаточно безопасный и максимально эффективный способ вернуть управление внешнему оператору.

Область действия операторов перехода и связанных с ними меток строго локализована. Метки, описанные вне процедур или функций, имеют своей областью действий только основной блок программы. Но метки, описанные внутри определения процедур или функций, имеют смысл только внутри них, поэтому запрещены переходы по Goto между процедурами и между процедурами и основным блоком. {104}

При практическом программировании на Паскале необходимость в использовании оператора Goto возникает не часто (если, конечно, не писать стилем Фортрана или Бейсика на Паскале). Иногда один переход позволяет избежать очень широких циклов, но злоупотребление переходами не будет признаком высокой культуры программирования.

Операторы Exit и Halt

Турбо Паскаль обладает средствами безусловного выхода из программных блоков (процедур, функций, основного блока программы). Это очень удобно, так как позволяет завершить программу или процедуру без предварительных переходов по меткам. К таким операторам завершения относятся вызовы системных процедур Exit и Halt.

Вызов Exit завершает работу своего программного блока. Если выполняется Exit в процедуре, то выполнение ее завершится и ход программы вернется к следующему за вызовом этой процедуры оператору. При этом процедура вернет значения, которые успели вычислиться к моменту выполнения Exit (если она должна их возвратить). Сама программа не прервется. Но если Exit выполняется в основном блоке программы, выход из него будет эквивалентен нормальному ее завершению. Процедура Exit — в некотором роде избыточная. Ее действие полностью эквивалентно безусловному переходу (Goto) на метку, стоящую перед последним словом END содержащей ее процедуры, функции или основного блока. Но использование Exit позволяет избежать лишней возни с метками и улучшает читаемость программ. Таким образом, Exit — это средство выхода из программного блока, а не из составного оператора, например цикла FOR. Вызов Exit может быть в трижды вложенном цикле процедуры, но его действие все равно будет относится к процедуре, как к программному блоку.

Процедура Halt, или более полно Halt(n), действует более грубо и менее разборчиво. Независимо от того, где она находится, ее выполнение завершает работу программы с кодом завершения n. Этот код впоследствии может быть проанализирован, в частности, командой IF ERRORLEVEL в среде MS-DOS. Значение ERRORLEVEL после остановки программы будет равно значению n. Значение n=0 соответствует нормальному коду завершения. Вызов процедуры Halt без параметра эквивалентен вызову Halt(0). {105}

На основе процедуры Halt можно легко построить программу, например ASK.PAS, для организации диалога в ВАТ-файлах MS-DOS (рис. 6.4).

 

VAR i: Word; { ======ПРОГРАММА ASK.PAS ======== } BEGIN {...вывод на экран текста альтернатив выбора... } Write('Введите Ваш выбор: '); ReadLn(i); { ввод номера альтернативы с экрана) Halt(i) { остановка программы и назначение } END. { ERRORLEVEL в MS-DOS номера i }

 

Рис. 6.4

Теперь в ВАТ-файле надо запускать откомпилированную программу ASK.EXE и сразу после нее анализировать, что будет находиться в переменной MS-DOS ERRORLEVEL.

Имеет смысл при нескольких вызовах Halt в тексте программы назначать им разные коды завершения. Тогда можно будет при отладке или работе определить, чем вызвано прерывание программы.

Процедуры и функции

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

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

PROCEDURE ИмяПроцедуры;

становится процедурой, и вместо этого составного оператора в основном блоке может подставляться одно лишь ИмяПроцедуры.

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

Синтаксис вызова процедуры прост. Ее выполнение активизируется указанием ее имени и списком переменных или значений, подставляемых на место параметров:

ИмяПроцедуры(Параметр1, Параметр2,); {106}

PROCEDURE ИмяПроцедуры (ПарамЗнач1: ТипЗнач1; ПарамЗнач2: ТипЗнач2; VAR ПарамПерем1: ТипПерем1; VAR ПарамПерем2: ТипПерем2;...); LABEL Перечисление меток внутри тела процедуры CONST Описание локальных констант процедуры TYPE Описание локальных типов VAR Описание локальных переменных Описание вложенных процедур и (или) функций BEGIN Тело процедуры END;

Рис. 6.5

Общая структура функций совпадает с процедурами, за исключением заголовка. Он записывается как

FUNCTION ИмяФункции(Список параметров):

ИмяСкалярногоТипаЗначенияФункций;

Что и как может возвращать функция при ее вызове, мы рассмотрим чуть позже.

Нетрудно заметить, что структура подпрограмм копирует структуру программы в целом (не считая заголовка и завершающей точки с запятой вместо точки после END). Порядок следования разделов описаний подчиняется тем же правилам, по которым строится вся программа.



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2022-11-01 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: