Х. Мёссенбёк, Н. Вирт - Язык программирования Оберон-2 (1160786), страница 4
Текст из файла (страница 4)
Шаг (step) должен быть отличным от нуля константнымвыражением. Если шаг не указан, он предполагается равным 1.Примеры:FOR i := 0 TO 79 DO k := k + a[i] ENDFOR i := 79 TO 1 BY -1 DO a[i] := a[i-1] END9.9 Операторы LoopОператор loop определяет повторное выполнение последовательности операторов.
Он завершаетсяпосле выполнения оператора выхода внутри этой последовательности (см. 9.10).ОператорLoop = LOOP ПоследовательностьОператоров END.Пример:LOOPReadInt(i);IF i < 0 THEN EXIT END;WriteInt(i)ENDОператоры loop полезны, чтобы выразить повторения с несколькими точками выхода, или вслучаях, когда условие выхода находится в середине повторяемой последовательности операторов.9.10 Операторы возврата и выходаОператор возврата выполняет завершение процедуры. Он обозначается словом RETURN, закоторым следует выражение, если процедура является процедурой-функцией.
Тип выражениядолжен быть совместим по присваиванию (см. Приложение A) с типом результата, определенным взаголовке процедуры (см. Гл. 10).Процедуры-функции должны быть завершены оператором возврата, задающим значениерезультата. В собственно процедурах оператор возврата подразумевается в конце тела процедуры.Любой явный оператор появляется, следовательно, как дополнительная (вероятно, дляисключительной ситуации) точка завершения.Оператор выхода обозначается словом EXIT.
Он определяет завершение охватывающегооператора loop и продолжение выполнения программы с оператора, следующего за операторомloop. Оператор выхода связан с содержащим его оператором loop контекстуально, а несинтаксически.9.11 Операторы WithОператоры with выполняют последовательность операторов в зависимости от результата проверкитипа и применяют охрану типа к каждому вхождению проверяемой переменной внутри этойпоследовательности операторов.16ОператорWith =WITH Охрана DO ПоследовательностьОператоров {"|" Охрана DOПоследовательностьОператоров} [ELSE ПоследовательностьОператоров]END.Охрана=УточнИдент ":" УточнИдент.Если v - параметр-переменная типа запись или переменная-указатель, и если ее статический типT0, операторWITH v: T1 DO S1 | v: T2 DO S2 ELSE S3 ENDимеет следующий смысл: если динамический тип v - T1, то выполняется последовательностьоператоров S1 в которой v воспринимается так, будто она имеет статический тип T1; иначе, еслидинамический тип v - T2, выполняется S2, где v воспринимается как имеющая статический тип T2;иначе выполняется S3.
T1 и T2 должны быть расширениями T0. Если ни одна проверка типа неудовлетворена, а ELSE отсутствует, программа прерывается.Пример:WITH t: CenterTree DO i := t.width; c := t.subnode ENDОбъявление процедуры состоит из заголовка процедуры и тела процедуры. Заголовок определяетимя процедуры и формальные параметры. Для связанных с типом процедур в объявлении такжеопределяется параметр-приемник.
Тело содержит объявления и операторы. Имя процедурыповторяется в конце объявления процедуры.Имеются два вида процедур: собственно процедуры и процедуры- функции. Последниеактивизируются обозначением функции как часть выражения и возвращают результат, которыйявляется операндом выражения. Собственно процедуры активизируются вызовом процедуры.Процедура является процедурой-функцией, если ее формальные параметры задают тип результата.Тело процедуры-функции должно содержать оператор возврата, который определяет результат.Все константы, переменные, типы и процедуры, объявленные внутри тела процедуры, локальныв процедуре. Поскольку процедуры тоже могут быть объявлены как локальные объекты,объявления процедур могут быть вложенными.
Вызов процедуры изнутри ее объявленияподразумевает рекурсивную активацию.Объекты, объявленные в окружении процедуры, также видимы в тех частях процедуры, вкоторых они не перекрыты локально объявленным объектом с тем же самым именем.ОбъявлениеПроцедурыЗаголовокПроцедурыТелоПроцедуры= ЗаголовокПроцедуры ";" ТелоПроцедуры идент.= PROCEDURE [Приемник] ИдентОпр [ФормальныеПараметры].= ПоследовательностьОбъявлений [BEGINПоследовательностьОператоров] END.ПослОбъявлений= {CONST {ОбъявлениеКонстант ";"} | TYPE{ОбъявлениеТипов";"} | VAR {ОбъявлениеПеременных ";"}}{ОбъявлениеПроцедуры ";" | ОпережающееОбъявление";"}.ОпережающееОбъявление = PROCEDURE"^" [Приемник] ИдентОпр[ФормальныеПараметры].Если объявление процедуры содержит параметр-приемник, процедура рассматривается каксвязанная с типом (см.
10.2). Опережающее объявление служит чтобы разрешить ссылки напроцедуру, чье фактическое объявление появляется в тексте позже. Списки формальныхпараметров опережающего объявления и фактического объявления должны быть идентичны.10.1 Формальные параметры17Формальные параметры - идентификаторы, объявленные в списке формальных параметровпроцедуры.
Им соответствуют фактические параметры, которые задаются при вызове процедуры.Подстановка фактических параметров вместо формальных происходит при вызове процедуры.Имеются два вида параметров: параметры-значения и параметры-переменные, обозначаемые всписке формальных параметров отсутствием или наличием ключевого слова VAR. Параметрызначения это локальные переменные, которым в качестве начального присваивается значениесоответствующего фактического параметра. Параметры-переменные соответствуют фактическимпараметрам, которые являются переменными, и означают эти переменные. Область действияформального параметра простирается от его объявления до конца блока процедуры, в котором онобъявлен. Процедура-функция без параметров должна иметь пустой список параметров. Онадолжна вызываться обозначением функции, чей список фактических параметров также пуст.
Типрезультата процедуры не может быть ни записью, ни массивом.ФормальныеПараметры ="(" [СекцияФП {";" СекцияФП }] ")" [":" УточненныйИдент].СекцияФП=[VAR] идент {"," идент} ":" Тип.Пусть Tf - тип формального параметра f (не открытого массива) и Ta - тип соответствующегофактического параметра a. Для параметров-переменных Ta и Tf должны быть одинаковымитипами или Tf должен быть типом запись, а Ta - расширением Tf. Для параметров-значений адолжен быть совместим по присваиванию с f (см. Прил.
A).Если Tf - открытый массив, то a должен быть совместимым массивом для f (см. Прил. A). Длинаf становится равной длине a.Примеры объявлений процедур:PROCEDURE ReadInt (VAR x: INTEGER);VAR i: INTEGER; ch: CHAR;BEGIN i := 0; Read(ch);WHILE ("0" <= ch) & (ch <= "9") DOi := 10*i + (ORD(ch)-ORD("0")); Read(ch)END;x := iEND ReadIntPROCEDURE WriteInt (x: INTEGER); (*0 <= x <100000*)VAR i: INTEGER; buf: ARRAY 5 OF INTEGER;BEGIN i := 0;REPEAT buf[i] := x MOD 10; x := x DIV 10; INC(i) UNTIL x = 0;REPEAT DEC(i); Write(CHR(buf[i] + ORD("0"))) UNTIL i = 0END WriteIntPROCEDURE WriteString (s: ARRAY OF CHAR);VAR i: INTEGER;BEGIN i := 0;WHILE (i < LEN(s)) & (s[i] # 0X) DO Write(s[i]); INC(i) ENDEND WriteString;PROCEDURE log2 (x: INTEGER): INTEGER;VAR y: INTEGER; (*предполагается x>0*)BEGINy := 0; WHILE x > 1 DO x := x DIV 2; INC(y) END;RETURN yEND log210.2 Процедуры, связанные с типом18Глобально объявленные процедуры могут быть ассоциированы с типом запись, объявленным в томже самом модуле.
В этом случае говорится, что процедуры связаны с типом запись. Связьвыражается типом приемника в заголовке объявления процедуры. Приемник может быть илипараметром-переменной типа Т, если Т - тип запись, или параметром-значением типа POINTER TOT (где T - тип запись). Процедура, связанная с типом T, рассматривается как локальная для него.ЗаголовокПроцедуры =PROCEDURE [Приемник] ИдентОпр [ФормальныеПараметры].Приемник="(" [VAR] имя ":" имя ")".Если процедура P связана с типом T0, она неявно также связана с любым типом T1, которыйявляется расширением T0. Однако процедура P' (с тем же самым именем что и P) может быть явносвязана с T1, перекрывая в этом случае связывание c P.
P' рассматривается как переопределение Pдля T1. Формальные параметры P и P' должны совпадать (см. Прил. A). Если P и T1экспортируются (см. Главу 4), P' также должна экспортироваться.Если v - обозначение, а P - связанная процедура, то v.P обозначает процедуру P, связанную сдинамическим типом v. Заметим, что это может быть процедура, отличная от той, что связана состатическим типом v. v передается приемнику процедуры P согласно правилам передачипараметров, определенным в Главе 10.1.Если r - параметр-приемник, объявленный с типом T, r.P^ обозначает (переопределенную)процедуру P, связанную с базовым для T типом.
В опережающем объявлении связанной процедурыи в фактическом объявлении процедуры параметр-приемник должен иметь одинаковый тип.Списки формальных параметров в обоих объявлениях должны быть идентичны.Примеры:PROCEDURE (t: Tree) Insert (node: Tree);VAR p, father: Tree;BEGIN p := t;REPEAT father := p;IF node.key = p.key THEN RETURN END;IF node.key < p.key THEN p := p.left ELSE p := p.right ENDUNTIL p = NIL;IF node.key < father.key THEN father.left := node ELSE father.right := node END;node.left := NIL; node.right := NILEND Insert;PROCEDURE (t: CenterTree) Insert (node: Tree); (*переопределение*)BEGINWriteInt(node(CenterTree).width);t.Insert^ (node) (* вызывает процедуру Insert, связанную с Tree *)END Insert;10.3 Стандартные процедурыСледующая таблица содержит список стандартных процедур.
Некоторые процедуры обобщенные, то есть они применимы к операндам нескольких типов. Буква v обозначаетпеременную, x и n - выражения, T - тип.Процедуры-функцииНазваниеABS(x)Тип аргументачисловой типASH(x, n) x, n: целый типТип результатаФункциясовпадает с типом абсолютное значениеxLONGINTарифметический сдвиг (x*2n)19CAP(x)CHARCHARx - буква: соответствующая заглавнаябукваCHR(x)целый типCHARсимвол с порядковым номером xнаибольшее целое, не превосходящееxENTIER(x) вещественный типLONGINTv: массив; n: целаяконстантаLONGINTLEN(v)LONG(x)v: массивSHORTINTINTEGERREALLONGINTINTEGERLONGINTLONGREALравносильно LEN(v, 0)тождествоMAX(T)T = основной типT = SETTINTEGERнаибольшее значение типа Tнаибольший элемент множестваMIN(T)T = основной типT = SETцелый типTINTEGERBOOLEANнаименьшее значение типа T0x MOD 2 = 1INTEGERINTEGERSHORTINTREALцелый типпорядковый номер xтождествотождествотождество (возможно усечение)число байт, занимаемых TLEN(v, n)ODD(x)ORD(x)CHARSHORT(x) LONGINTINTEGERLONGREALSIZE(T)любой типдлина v в измерении n (первоеизмерение = 0)Собственно процедурыНазваниеТипы аргументовASSERT(x)x: логическое выражениеASSERT(x, n)x: логическое выражение; n:целаяконстантаx: символьный массив, строка; v:символьный массивCOPY(x, v)Функцияпрерывает выполнениепрограммы, если не xпрерывает выполнениепрограммы, если не xv := xDEC(v)DEC(v, n)целый типv, n: целый типv := v - 1v := v - nEXCL(v, x)HALT(n)v: SET; x: целый типцелая константаv := v - {x}прерывает выполнение программыINC(v)INC(v, n)целый типv, n: целый типv := v + 1v := v + nINCL(v, x)NEW(v)v: SET; x: целый типуказатель на запись или массивфиксированной длиныv := v + {x}размещает v ^NEW(v, x0, ..., xn)v: указатель на открытый массив; xi:целый типразмещает v^ с длинами x0..