ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП |
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы. |
Часть 9 ГЛАВА 7. ОПЕРАТОРЫ. Операторы описывают те алгоритмические действия, которые должны выполняться. Операторам могут предшествовать метки, которые можно использовать для ссылок в операторах goto. оператор ДДДВДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДц і ЪДДДДДї ЪДї ш і ЪДДДДДДДДДДДДДДДДї ш АДціметкаГДДці:ГДЩ ГДДціпростой операторГДДґ АДДДДДЩ АДЩ і АДДДДДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДДДДДї і АДДці структурный ГДДЩ і оператор і АДДДДДДДДДДДДДДДДЩ Как показано в главе 1, метка может быть последовательностью цифр от 0 до 9999 или идентификатором. Существуют 2 главных типа операторов: простой оператор и структурный оператор. Простые операторы. Простым оператором является такой оператор, который не содержит в себе других операторов. ЪДДДДДДДДДДДДДДДДДДДДДї простой оператор ДДДДВДДДціоператор присваиванияГДДДДДДДц і АДДДДДДДДДДДДДДДДДДДДДЩ ш і ЪДДДДДДДДДДДДДДДДДДДДДї і ГДДДці оператор процедуры ГДДДґ і АДДДДДДДДДДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДДДДДДДДДДї і АДДДці оператор перехода ГДДДЩ АДДДДДДДДДДДДДДДДДДДДДЩ Операторы присваивания. Оператор присваивания заменяет текущее значение переменной новым значением, которое определяется выражением, или определяет выражение, значение которого должно возвращаться функцией. ЪДДДДДДДДДДДї ЪДДї ЪДДДДДДДДДї оператор ДДВДДціссылка на ГДДДДДДці:=ГДДцівыражениеГДДц присваивания і іпеременную і ш АДДЩ АДДДДДДДДДЩ і АДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДДї і АДДціидентификаторГДЩ і функции і АДДДДДДДДДДДДДЩ Выражение должно быть совместимо по присваиванию с типом переменной или типом значения, возвращаемого функцией в качестве результата (см. раздел "Совместимость типов" в главе 3). Приведем некоторые примеры оператора присваивания: X : = Y + Z; Done : = (I >= 1) and (I < 100); Huе1 : = (Blue, Sucс(C)); I : = Sgr(J) - I * K; Присваивание объектов. Правила совместимости типов объектов по присваиванию позволяют экземпляру объектного типа присвоить экземпляр любого из его порожденных типов. Такое присваивание приводит к проекции порожденного объекта на пространство предка. Например, пусть даны экземпляр F типа Field и экземпляр Z типа ZipField, то тогда присваивание F := Z будет копировать только поля X, Y, Len и Name. (Типы объектов обсуждены в главе 5.) Присваивание экземпляру объектного типа не включает инициализации экземпляра. Так, присваивание F := Z не означает, что вызов констрактора для F может быть опущен. Оператор процедуры. Оператор procedure определяет активизацию процедуры, обозначенную с помощью идентификатора процедуры. Если соответствующее объявление процедуры содержит список формальных параметров, то оператор процедуры должен содержать в себе соответствующий ему список фактических параметров (параметры, список которых приводится в определении, являются формальными параметрами, а в операторе вызова процедуры они являются фактическими параметрами). При вызове происходит передача фактических параметров формальным параметрам. ЪДДДДДДДДДДДДДї оператор ДДДДціидентификаторГДДВДДДДДДДДДДДДДДДДДДДДДДДДДДц процедуры і процедуры і і ЪДДДДДДДДДДДДДДДДДДї ш АДДДДДДДДДДДДДЩ АДцісписок фактическихГДЩ і параметров і АДДДДДДДДДДДДДДДДДДЩ Приведем некоторые примеры операторов процедур: PrintHeading; Transpose(A, N, M); Find(Name, Address); Примечание: Процедуру можно также вызвать через переменную типа процедура. Для получения более подробной информации обратитесь к разделу "Процедурные типы" в главе 8. Вызовы методов, констракторов и дестракторов. Синтаксис оператора процедуры был расширен для того, чтобы разрешить указания квалификатора метода, означающий замену идентификатора процедуры, необходимой процедурой, констрактором или дестрактором. Квалификатор метода используется для двух целей : Во-первых: в случае виртуального метода актуальный (времени выполнения) тип экземпляра определяет, какую реализацию метода активизировать. Во-вторых: экземпляр сам становится неявным действительным параметром метода. Он соответствует формальному параметру Self, который имеет тип, соответствующий активированному методу. Внутри метода оператор процедуры позволяет квалифицировать идентификатор метода для активации указанного метода. Объектный тип, используемый при квалификации идентификатора должен быть тем же самым, что и объектный тип метода или его предка. Этот тип активации называется квалифицированной активацией. Квалифицированная активация никогда не использует механизм выбора виртуального метода - вызов всегда статический и всегда вызывает заданный метод. Неявный параметр Self квалифицированной активации становится вместо Self метода, содержащего вызов. Квалифицированная активация используется внутри перекрывающего метода для активации перекрытого метода. Используя типы, объявленные раньше, приведем пример квалифицированной активации: constructor NumField.Init(FX, FY, FLen: Integer; FName: String; FMin, FMax: Longint); begin Field.Init(FX, FY, FLen, FName); Value := 0; Min := FMin; Max := FMax; end; function ZipField.PutStr(S: String): Boolean; begin PutStr := (Length(S) = 5) and NumField.PutStr(S); end; Как демонстрируют эти примеры, квалифицированная активация используется перекрывающим методом для использования кода метода, который он перекрыл. Операторы перехода (goto). Оператор goto вызывает передачу управления оператору, которому предшествует метка, указанная в данном операторе goto. Синтаксическая схема оператора goto имеет следующий вид: ЪДДДДї ЪДДДДДї оператор перехода ДДДціgotoГДДДціметкаГДДДц АДДДДЩ АДДДДДЩ При использовании оператора перехода должны соблюдаться следующие правила: - Метка, которая указывается в операторе перехода, должна находиться в том же блоке или модуле, что и сам оператор перехода. Другими словами, не допускаются переходы из процедуры или функции или внутрь нее. - Переход извне внутрь структурного оператора (то есть переход на более глубокий уровень вложенности) может вызвать непредсказуемые эффекты, хотя компилятор не выдает сообщения об ошибке. Структурные операторы. Структурные операторы операторов, порядок выполнения которых должен быть последовательным (составные операторы и операторы над записями (with)), определяемым условной передачей управления (условные операторы) или повторяющимся (операторы цикла). ЪДДДДДДДДДДДДДДДДДДДДДДДї структурный ДДДДВДДДДці составной оператор ГДДДДДДДц оператор і АДДДДДДДДДДДДДДДДДДДДДДДЩ ш і ЪДДДДДДДДДДДДДДДДДДДДДДДї і ГДДДДці условный оператор ГДДДґ і АДДДДДДДДДДДДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДДДДДДДДДДДДї і ГДДДДці оператор цикла ГДДДґ і АДДДДДДДДДДДДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДДДДДДДДДДДДї і АДДДДці оператор над записями ГДДДЩ АДДДДДДДДДДДДДДДДДДДДДДДЩ Составные операторы. Составные операторы задают порядок выполнения операторов, являющихся их элементами. Они должны выполняться в том порядке, в котором они записаны. Составные операторы обрабатываются, как один оператор, что имеет решающее значение там, где синтаксис Паскаля допускает использование только одного оператора. Операторы заключаются в ограничители begin и end и отделяются друг от друга точками с запятой. ЪДДДДДї ЪДДДДДДДДї ЪДДДї составной ДДДДціbeginГДДДДДДціоператорГДДДДВДДціendГДДц оператор АДДДДДЩ ш АДДДДДДДДЩ і АДДДЩ і ЪДДДї і АДДДДДґ ; ічДДДДДДЩ АДДДЩ Приведем пример составного оператора: begin Z : = X; X : = Y; Y : = Z; end; Условные операторы. Условные операторы позволяют выбрать для выполнения один из составных операторов (или не выбрать ни одного). ЪДДДДДДДДДДДДДДДї условный оператор ДДВДДці оператор if ГДДДДДДДц і АДДДДДДДДДДДДДДДЩ ш і ЪДДДДДДДДДДДДДДДї і АДДці оператор case ГДДДЩ АДДДДДДДДДДДДДДДЩ Оператор if. Синтаксис оператора if можно представить следующим образом: ЪДДї ЪДДДДДДДДДї ЪДДДДї ЪДДДДДДДДї оператор if ДДціifГДДцівыражениеГДДціthenГДДціоператорГДДВДДї АДДЩ АДДДДДДДДДЩ АДДДДЩ АДДДДДДДДЩ і і ЪДДДДДДДДДДДДДДДДДДДДДДДДЩ і і ЪДДДДї ЪДДДДДДДДї щ АДДціelseГДДціоператорГДДДДДДДДДц АДДДДЩ АДДДДДДДДЩ В выражении должен получаться результат, имеющий стандартный тип Boolean. Если результатом выражения является истинное значение (True), то выполняется оператор, следующий за ключевым словом then. Если результатом выражения является значение False и присутствует ключевое слово else, то выполняется оператор, следующий за ключевым словом else. Если ключевое слово else отсутствует, то не выполняется никакой оператор. Синтаксическая неоднозначность, возникающая в конструкции: if e1 then if e2 then s1 else s2 разрешается путем следующей интерпретации этой конструкции: if e1 then begin if e2 then s1 else s2 end; В общем случае ключевое слово else связывается с ближайшим ключевым словом if, с которым еще не ассоциировано else. Приведем два примера оператора if: if Х < 1.5 then X : = X + Y else Z : = 1.5; if P1 <> nil then P1 : = P1^. Father; Оператор case. Оператор case состоит из выражения (селектора) и списка операторов, каждому из которых предшествует одна или более констант (они называются константами выбора) или ключевое слово else. Селектор должен иметь порядковый тип размера байт или слово. Таким образом, строковый тип и тип LongInt являются недопустимыми типами селектора. Все константы выбора должны быть уникальными и иметь порядковый тип, совместимый с типом селектора. ЪДДДДї ЪДДДДДДДДДї ЪДДї ЪДДДДї оператор case ДДціcaseГДДцівыражениеГДДціofГДДДДДціcaseГДДВДДї АДДДДЩ АДДДДДДДДДЩ АДДЩ ш АДДДДЩ і і і ЪДДДДї і і АДДДґ ; ічДЩ і АДДДДЩ і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ і ЪДДДї АДВДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДціendГДДц і ЪДДДДДДДДДДї ш і ЪДї ш АДДДЩ АДДціветвь elseГДДЩ АДці;ГДДЩ АДДДДДДДДДДЩ АДЩ ЪДДДДДДДДДДДДДДДДДДДДї ЪДДДДДДДДДї і ЪДДї ЪДДДДДДДДДї щ ЪДї ЪДДДДДДДДї case ДДДціконстантаГДБДці..ГДціконстантаГДДДВДДці:ГДціоператорГДДц ш АДДДДДДДДДЩ АДДЩ АДДДДДДДДДЩ і АДЩ АДДДДДДДДЩ і ЪДДї і АДДДДДДДДДДДДДДДДДґ, ічДДДДДДДДДДДДДДДЩ АДДЩ ЪДДДДї ЪДДДДДДДДї ветвь else ДДДДціelseГДДДціоператорГДДДц АДДДДЩ АДДДДДДДДЩ Оператор case приводит к выполнению оператора, которому предшествует константа выбора, равная значению селектора или диапазону выбора, в котором находится значение селектора. Если такой константы выбора или такого диапазона выбора не существует, то выполняется оператор, следующий за ключевым словом else. Если ветвь else отсутствует, то не выполняется никакой оператор. Приведем некоторые примеры оператора case: case Operator of Plus : X := X + Y; Minus: X := X - Y; Times: X := X * Y; end; case I of 0, 2, 4, 6, 8: Writeln('Even digit'); 1, 3, 5, 7, 9: Writeln('Odd digit'); 10..100 : Writeln('Between 10 and 100'); else Writeln('Negative or greater than 100'); end; Операторы цикла. Операторы цикла задают повторное выполнение определенных операторов. ЪДДДДДДДДДДДДДДДДДї оператор цикла ДДДВДДці оператор repeat ГДДДДДДц і АДДДДДДДДДДДДДДДДДЩ ш і ЪДДДДДДДДДДДДДДДДДї і ГДДці оператор while ГДДґ і АДДДДДДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДДДДДДї і АДДці оператор for ГДДЩ АДДДДДДДДДДДДДДДДДЩ Если число повторений заранее известно, то подходящей конструкцией является оператор for. В противном случае следует использовать операторы while или repeat. Операторы цикла repeat. В операторе цикла repeat выражение, которое управляет повторным выполнением последовательности операторов, содержится внутри оператора repeat. ЪДДДДДДї ЪДДДДДДДДї ЪДДДДДї ЪДДДДДДДДДї оператор ДДціrepeatГДДДДціоператорГДДВДціuntilГДДцівыражениеГДДц repeat АДДДДДДЩ ш АДДДДДДДДЩ і АДДДДДЩ АДДДДДДДДДЩ і ЪДДДї і АДДДДґ ; ічДДДДЩ АДДДЩ Результатом выражения должен быть результат булевского типа. Операторы, заключенные между ключевыми словами repeat и until, выполняются последовательно до тех пор, пока результат выражения не примет значения True. Последовательность операторов выполняется по крайней мере один раз, поскольку вычисление выражения производится после каждого выполнения последовательности операторов. Приведем примеры оператора repeat: repeat K := I mod J; I := J; J := K; until J = O; repeat Write ('Enter Value(0..9):'); Readln (I); until (I >= 0) and (I <= 9); Операторы цикла while. Оператор цикла while содержит в себе выражение, которое управляет повторным выполнением оператора (который может быть составным оператором). ЪДДДДДї ЪДДДДДДДДДї ЪДДї ЪДДДДДДДДї оператор ДДДціwhileГДДцівыражениеГДДціdoГДДціоператорГДДц while АДДДДДЩ АДДДДДДДДДЩ АДДЩ АДДДДДДДДЩ Выражение, с помощью которого производится управление повторением оператора, должно иметь булевский тип. Вычисление его производится до того, как внутренний оператор будет выполнен. Внутренний оператор выполняется повторно до тех пор, пока выражение принимает значение True. Если выражение с самого начала принимает значение False, то оператор, содержащийся внутри оператора цикла while, не выполняется ни разу. Примерами оператора цикла while могут служить: while Data[I] <> X do I := I + 1; while I > 0 do begin if Odd(I) then Z := Z * X; I := I div 2; X := Sqr(X); end; while not Eof(InFile) do begin Readln (InFile, Line); Process (Line); end; Операторы цикла for. Оператор цикла for вызывает повторяющееся выполнение оператора (который может быть составным оператором), пока управляющей переменной присваивается возрастающая последовательность значений. ЪДДДї ЪДДДДДДДДДДДї ЪДДї ЪДДДДДДДДї оператор ДДДціforГДДціуправляющаяГДДці:=ГДДціисходноеГДДДї for АДДДЩ іпеременная і АДДЩ ізначениеі і АДДДДДДДДДДДЩ АДДДДДДДДЩ і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ і ЪДДї і ЪДціtoГДДДДДї ЪДДДДДДДДї ЪДДї ЪДДДДДДДДї АДДці АДДЩ ГДДціконечноеГДДціdoГДДціоператорГДДДц і ЪДДДДДДї і ізначениеі АДДЩ АДДДДДДДДЩ АДціdowntoГДЩ АДДДДДДДДЩ АДДДДДДЩ ЪДДДДДДДДДДДДДДДДДДДДДДДДї управляющая переменная ДДДціидентификатор переменнойГДДДц АДДДДДДДДДДДДДДДДДДДДДДДДЩ ЪДДДДДДДДДї исходное значение ДДДДцівыражениеГДДДц АДДДДДДДДДЩ ЪДДДДДДДДДї конечное значение ДДДДцівыражениеГДДДц АДДДДДДДДДЩ В качестве управляющей переменной должен использоваться идентификатор переменной (без какого-либо квалификатора), который обозначает переменную, обьявленную локальной в блоке, в котором содержится оператор for. Управляющая переменная должна иметь порядковый тип. Начальное и конечное значения должны иметь тип, совместимый по присваиванию с этим порядковым типом. Когда начинает выполняться оператор for, начальное и конечное значения определяются один раз, и эти значения сохраняются на протяжении всего выполнения оператора for. Оператор, который содержится в теле оператора for, выполняется один раз для каждого значения в диапазоне между начальным и конечным значением. Управляющая переменная всегда инициализируется начальным значением. Когда оператор for использует ключевое слово to, значение управляющей переменной увеличивается при каждом повторении на единицу. Если начальное значение превышает конечное значение, то содержащийся в теле оператора for оператор не выполняется. Когда в операторе цикла используется ключевое слово downto, значение управляющей переменной уменьшается при каждом повторении на единицу. Если начальное значение в таком операторе меньше, чем конечное значение, то содержащийся в теле оператора цикла оператор не выполняется. Если оператор, содержащийся в теле оператора for, изменяет значение управляющей переменной, то это является ошибкой. После выполнения оператора for значение управляющей переменной становится неопределенным, если только выполнение оператора for не было прервано с помощью оператора перехода. Если принять во внимание эти ограничения, то оператор for V := Expr1 to Expr2 do Body; эквивалентен оператору begin Temp1 := Expr1; Temp2 := Expr2; if Temp1 <= Temp2 then begin V := Temp1; Body; while V <> Temp2 do begin V := Succ(V); Body; end; end; end; и оператор цикла for for V := Expr1 downto Expr2 do Body; эквивалентен оператору begin Temp1 := Expr1; Temp2 := Expr2; if Temp1 >= Temp2 then begin V := Temp1; Body; while V <> Temp2 do begin V := Pred(V); Body; end; end; end; где Temp1 и Temp2 - вспомогательные переменные, тип которых совпадает с основным типом переменной V и которые не встречаются в другом месте программы. Приведем примеры оператора цикла for: for I := 2 to 63 do if Data[I] > Max then Max := Data[I]; for I := 1 to 10 do for J := 1 to 10 do begin X := 0; for K := 1 to 10 do X := X + Mat1[I, K] * Mat2[K, J]; Mat [I, J] := X; end; for C := Red to Blue do Check(C); Оператор над записями with. В операциях над записями оператор with удобно использовать для краткого обращения к полям записи и к полям, методам, констрактору и дестрактору объекта. В операторе with к полям одной или более конкретных переменных типа запись можно обращаться, используя только идентификаторы полей. Оператор with имеет следующий синтаксис: ЪДДДДї ЪДДДДДДДДДДДДДДДї ЪДДї ЪДДДДДДДДї оператор ДДціwithГДДДДДціссылка на пере-ГДДВДціdoГДДціоператорГДДц with АДДДДЩ ш іменную типа і і АДДЩ АДДДДДДДДЩ і ізапись і і і іили объект і і і АДДДДДДДДДДДДДДДЩ і і ЪДДДї і АДДДДДДДДґ , ічДДДДДДДДЩ АДДДЩ ссылка на переменную ЪДДДДДДДДДДДДДДДДДДДДї типа запись или объект ДДДціссылка на переменнуюГДДц АДДДДДДДДДДДДДДДДДДДДЩ Приведем пример оператора with: with Data do if Month = 12 then begin Month := 1; Year := Year + 1; end else Month := Month + 1; Это эквивалентно следующему: if Date.Month = 12 then begin Date.Month := 1; Date.Year := Date.Year + 1; end else Date.Month := Date.Month + 1; В операторе with сначала производится проверка каждой ссылки на переменную, а именно: можно ли ее интерпретировать, как поле записи. Если можно, то она всегда интерпретируется именно таким образом, даже если имеется доступ к переменной с тем же именем. Допустим, обьявлены следующие переменные: type Point = record X, Y: Integer; end; var X : Point; Y : Integer; В этом случае и к X, и к Y можно обращаться, как к переменной или как к полю записи. В операторе: with X do begin X := 10; Y := 25; end; X между ключевыми словами with и do относится к переменной типа point, а в составном операторе X и Y ссылаются на X.X и X.Y. Оператор with V1, V2, ... Vn do S; эквивалентен операторам: with V1 do with V2 do .... with Vn do S; В обоих случаях, если Vn является полем и V1, и V2, то она интерпретируется как V2.Vn, а не как V1.Vn. Если выборка переменной типа запись связана с индексированием массива или вычислением указателя, то эти действия производятся до того, как будет выполняться составной оператор. |