ЭЛЕКТРОННАЯ БИБЛИОТЕКА КОАПП |
Сборники Художественной, Технической, Справочной, Английской, Нормативной, Исторической, и др. литературы. |
Часть 9 Глава 7. Операторы Операторы описывают те алгоритмические действия, которые должны выполняться. Операторам могут предшествовать метки, которые можно использовать для ссылок в операторах перехода. оператор ДВДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД і і і ЪДДДДДї ХНННё і і ЪДДДДДДДДДДДДДДДДДДї і АіметкаГДі : ГДЩ ГДДДі простой оператор ГДДДґ АДДДДДЩ ФНННѕ і АДДДДДДДДДДДДДДДДДДЩ і і ДДДДДДДДДДДДДДДДДДДДї і АДДДі структурный ГДДЩ і оператор і АДДДДДДДДДДДДДДДДДДДЩ Простые операторы Простым оператором является такой оператор, который не содержит в себе других операторов. ЪДДДДДДДДДДДДДДДДДДДДДДДї простой оператор ДДДДВДДДДДі оператор присваивания ГДДДДДДДДДД і АДДДДДДДДДДДДДДДДДДДДДДДЩ і ЪДДДДДДДДДДДДДДДДДДДДДДДї і ГДДДДДі оператор процедуры ГДДДДґ і АДДДДДДДДДДДДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДДДДДДДДДДДДї і АДДДДДі оператор перехода ГДДДДЩ АДДДДДДДДДДДДДДДДДДДДДДДЩ Оператор присваивания Оператор присваивания заменяет текущее значение переменной новым значением, которое определяется выражением, или определяет выражение, значение которого должно возвращаться функцией. ЪДДДДДДДДДДДДДДДДДДДДДДї ХНННё оператор ДДВі ссылка на переменную ГДДДДДДі :=ГДДї присваивания і АДДДДДДДДДДДДДДДДДДДДДДЩ ФНННѕ і і і і і ЪДДДДДДДДДДДДДДДДДДДДДДДї і і Аі идентификатор функции ГДДДДЩ і АДДДДДДДДДДДДДДДДДДДДДДДЩ ЪДДДДДДДДДДЩ і ЪДДДДДДДДДДДї АДі выражение ГДДДДД АДДДДДДДДДДДЩ Выражение должно быть совместимо по присваиванию с типом переменной или типом значения, возвращаемого функцией в качестве результата (см. раздел "Совместимость типов" в Главе 3 "Типы"). Приведем некоторые примеры операторов присваивания: X := Y + Z Done := (I>=1) and (I<100); Huel := [blue,Succ(C)]; I := Sqr(J) - I*K; Присваивания для объектного типа Правила совместимости при присваивании объектных типов позволяют присваивать экземпляр объектного типа экземпляру любого из наследующих типов. Такое присваивание представляет собой проекцию потомка на спиновое простанство его предка. Например, если имеется экземпляр F поля Field и экземпляр Z типа ZipField, то присваивание F := Z копирует только поля X, Y, Len и Name. Присваивание экземпляра объектного типа не приводит к инициализации этого экземпляра. В предыдущем примере F := Z не означает. что можно опустить вызов конструктора для F. Примечание: Более подробно объектные типы обсуждаются в Главе 5. Операторы процедуры Оператор процедуры определяет активизацию процедуры, обозначенную с помощью идентификатора процедуры. Если соответствующее описание процедуры содержит список формальных параметров, то оператор процедуры должен содержать в себе соответствующий ему сп исок фактических параметров (параметры, список которых приводится в определении, являются формальными параметрами, а в операторе вызова процедуры они являются фактическими параметрами). При вызове происходит передача фактических параметров формальным пар аметрам. ЪДДДДДДДДДДДДДДДДДДДДДДДДДї оператор ДДДі идентификатор процедуры ГДВДДДДДДДДДДДДДДДДДДД процедуры АДДДДДДДДДДДДДДДДДДДДДДДДДЩ і і ЪДДДДДДДДї і і і список і і і і факти- і і Аі ческих ГДЩ і пара- і і метров і АДДДДДДДДЩ Приведем некоторые примеры операторов процедур: PrintHeaing; Transpose(A,N,M); Fin(Name,Address); Примечание: Процедуры можно вызывать также через процедурные переменные. См. раздел "Процедурные типы". Вызов метода, конструктора и деструктора Синтаксис оператора процедуры расширен таким образом, чтобы позволить десигнатору метода, обозначающему процедуру, конструктор или деструктор, переопределять идентификатор процедуры. Обозначаемый десигнатором метода экземпляр служит двум целям. Во-первых, в случае виртуального метода фактический (определяемый во время выполнения) тип экземпляра определяет, какой экземпляр метода активизирован. Во-вторых, сам экземпляр становится неявным параметром метода это соответствует формальному параметру-переменной с именем 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; Как показывает этот пример, уточненная активизация позволяет переопределяющим методам снова использовать код методов, которые они переопределяют. Операторы перехода Оператор перехода вызывает передачу управления оператору, которому предшествует метка, указанная в данном операторе перехода. Синтаксическая схема оператора перехода имеет следующий вид: ХНННННННё ЪДДДДДДДї оператор перехода ДДДДДі gоtо ГДДДДДДі метка ГДДДДДД ФНННННННѕ АДДДДДДДЩ При использовании оператора перехода должны соблюдаться следующие правила: 1. Метка, которая указывается в операторе перехода, должна находиться в том же блоке или модуле, что и сам оператор перехода. Другими словами, не допускаются переходы из процедуры или функции или внутрь нее. 2. Переход извне внутрь структурного оператора (то есть переход на более глубокий уровень вложенности) может вызвать непредсказуемые эффекты, хотя компилятор не выдает сообщения об ошибке. Структурные операторы Структурные (или структурированные) операторы строятся из других операторов, порядок выполнения которых должен быть последовательным (составные операторы и операторы над записями), определяемым условной передачей управления (условные операторы) или повторяющимся (операторы цикла). ЪДДДДДДДДДДДДДДДДДДДДї структурный оператор ДДДДДДі составной оператор ГДДДДДДДДДДДД і АДДДДДДДДДДДДДДДДДДДДЩ і ЪДДДДДДДДДДДДДДДДДДДДї і ГДДДі условный оператор ГДДДДДі і АДДДДДДДДДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДДДДДДДДДДДї і ГДДі оператор цикла ГДДДДі і АДДДДДДДДДДДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДДДДї і АДДі оператор with ГДДДДДДДДДДДДЩ АДДДДДДДДДДДДДДДЩ Составные операторы Составные операторы задают порядок выполнения операторов, являющихся их элементами. Они должны выполняться в том порядке, в котором они записаны. Составные операторы обрабатываются, как один оператор, что имеет решающее значение там, где синтаксис П аскаля допускает использование только одного оператора. Операторы заключаются в ограничители begin и end, и отделяются друг от друга точкой с запятой. ХНННННННё ЪДДДДДДДДДДї ХНННННННё составной оператор ДДі begin ГДДі оператор ГДВі end ГДДДД ФНННННННѕ АДДДДДДДДДДЩ і ФНННННННѕ і ХННННё і АДДДДДДДДДДДДДґ ; ГДДДДДДДЩ ФННННѕ Приведем пример составного оператора: begin Z := X; X := Y; Y := Z; end; Условные операторы Условные операторы позволяют выбрать для выполнения один из составных операторов (или не выбрать ни одного). ЪДДДДДДДДДДДДДДДї Условный оператор ДДВДДДДДДДДДДДі оператор if ГДДДДДДДДДДДДД і АДДДДДДДДДДДДДДДЩ і ЪДДДДДДДДДДДДДДДДДДДДї і АДДі оператор case ГДДДДДДДДЩ АДДДДДДДДДДДДДДДДДДДДЩ Оператор if Синтаксис оператора if можно представить следующим образом: ХННННё ЪДДДДДДДДДї ХННННННё ЪДДДДДДДДї Оператор if-і if ГДівыражениеГДі then ГДіоператорГДДВДї ФННННѕ АДДДДДДДДДЩ ФННННННѕ АДДДДДДДДЩ і і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ і і ХННННННё ЪДДДДДДДДДДДДї АДі else ГДДДі оператор ГДДДДДДДДДДДДДДД ФННННННѕ АДДДДДДДДДДДДЩ В выражении должен получаться результат, имеющий стандартный булевский тип. Если результатом выражения является истинное значение (True), то выполняется оператор, следующий за ключевым словом then. Если результатом выражения является значение False и присутствует ключевое слово else, то выполнятся оператор, следующий за ключевым словом else. Если ключевое слово else отсутствует, то никакой оператор не выполняется. Синтаксическая неоднозначность, возникающая в конструкции: if e1 then e2 else e3 разрешается путем следующей интерпретации этой конструкции: if e1 then begin if e2 then s1 else s2 end В общем случае ключевое слово else связывается с ближайшим ключевым словом if, которое еще не связано с ключевым словом else. Приведем два примера оператора if: if X < 1.5 then Z := X+Y else Z := 1.5; if P1 <> nil then P1 := P1^.father; Оператор варианта (case) Оператор варианта (casе) состоит из выражения (переключателя) и списка операторов, каждому из которых предшествует одна или более констант (они называются константами выбора) или ключевое слово else. Переключатель (селектор) должен иметь перечислимы й тип (размером в байт или слово), и перечислимые значения верхней и нижней границы этого типа должны лежать в диапазоне от -32768 до 32767. Таким образом, строковый тип и длинный целый тип являются недопустимыми типами переключателя. Все константы выбор а дожны быть уникальными и иметь перечислимый тип, совместимый с типом переключателя. ХННННННё ЪДДДДДДДДДї ХННННННё ДДДДДДДї оператор ДДДі case ГДДівыражениеГДі of ГВДґ casе ГДВДї варианта ФННННННѕ АДДДДДДДДДЩ ФННННННѕі ДДДДДДДЩ і і і ХНННё і і АДДґ ; ГДДДЩ і ФНННѕ і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ і ХННННННё АВДДДДДДДДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДі end ГДДДДД і ЪДДДДДДДДДДДДї і ХНННННё ФННННННѕ АДі ветвь else ГДДДДЩ АДДі end ГДЩ АДДДДДДДДДДДДЩ ФНННННѕ ЪДДДДДДДДДДДДДДДДДДДДДДї і і ЪДДДДДДДДДДДї і ХНННННё ЪДДДДДДДДДї ХНННё casе -і константа ГДБі .. ГіконстантаГДДВі : ГДДї АДДДДДДДДДДДЩ ФНННННѕ АДДДДДДДДДЩ і ФНННѕ і і ХНННё і ЪДДДДДДЩ АДДДДДДДДДДДДДДДДДі , іДДДДДДДДДДДДДДДЩ і ЪДДДДДДДДДДї ФНННѕ Аі оператор ГДДД АДДДДДДДДДДЩ ХНННННё ЪДДДДДДДДДДї ветвь else ДДДДДДі elseГДДДі оператор ГДДДДДДДДДДДДДДДДДДДДД ФНННННѕ АДДДДДДДДДДЩ Оператор варианта case приводит к выполнению оператора, которому предшествует константа выбора, равная значению переключателя или диапазону выбора, в котором находится значение переключателя. Если такой константы выбора или такого диапазона выбора н е существует и присутствует ветвь else, то выполнятся оператор, следующий за ключевым словом else. Если же ветвь else отсутствует, то никакой оператор не выполняется. Приведем некоторые примеры оператора варианта: 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('Четная цифра'); 1, 3, 5, 7, 9: Writeln('Нечетная цифра'); 10..100: Writeln('Между 10 и 100'); end; Оператор цикла Оператор цикла задает повторное выполнение определенных операторов. ЪДДДДДДДДДДДДДДДДДї Оператор цикла ДДДДДДДДВДДДі оператор repeat ГДДДДДДДДДДДДДДДД і АДДДДДДДДДДДДДДДДДЩ і ЪДДДДДДДДДДДДДДДДДї і ГДДДі оператор while ГДДДДґ і АДДДДДДДДДДДДДДДДДЩ і і ЪДДДДДДДДДДДДДДДДДї і АДДДі оператор for ГДДДДЩ АДДДДДДДДДДДДДДДДДЩ Если число повторений заранее известно, то подходящей конструкций является оператор for. В противном случае следует использовать операторы while или repeat. Оператор цикла с постусловием (repeat) В операторе цикла с постусловием (начинающимся со слова repeat) выражение, которое управляет повторным выполнением последовательности операторов содержится внутри оператора repeat. ХННННННННё ЪДДДДДДДДї ХННННННННё ЪДДДДДДДДї оператор -і repeat ГДДДґоператорГДВДі until ГДіоператорГДДДДДДД цикла с ФННННННННѕ АДДДДДДДДЩ і ФННННННННѕ АДДДДДДДДЩ постусловием і ХНННё і АДДДДґ ; іДДЩ ФНННѕ Результатом выражения должен быть результат булевского типа. Операторы, заключенные между ключевыми словами repeat и until, выполняются последовательно до тех пор, пока результат выражения не примет значение True. Последовательность операторов выпол нится по крайней мере один раз, поскольку вычисление выражения производится после каждого выполнения последовательности операторов. Приведем примеры оператора цикла с постусловием: repeat K := I mod J; I := J; J := K; until J = 0; repeat Write('Введите значение (0..9):'); Readln(I); until (I >= 0) and (I <= 9); Операторы цикла с предусловием (while) Оператор цикла с предусловием (начинающийся с ключевого слова while) содержит в себе выражение, которое управляет повторным выполнением оператора (который может быть составным оператором). ХНННННё ЪДДДДДДДДДї ХННННё ЪДДДДДДДДї оператор цикла -іwhileГДДівыражениеГДі dо ГДіоператорГДДДДДД с предусловием ФНННННѕ АДДДДДДДДДЩ ФННННѕ АДДДДДДДДЩ Выражение, с помощью которого осуществляется управление повторением оператора, должно иметь булевский тип. Вычисление его производится до того, как внутренний оператор будет выполнен. Внутренний оператор выполнятся повторно до тех пор, пока выражени е принимает значение Тruе. Если выражение с самого начала принимает значение False, то оператор, содержащийся внутри оператора цикла с предусловием, не выполняется. Примерами операторов цикла с предусловием могут служить следующие операторы: 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 ГДіуправляющая переменнаяГДі := ГДї с параметром ФНННННѕ АДДДДДДДДДДДДДДДДДДДДДДЩ ФННННѕ і ЪДДДДДДДДДДДДДДДДДДДДДДДДї і ЪДДДДДДДДДДДДДДДґ начальное значение іДДДДДДДЩ і АДДДДДДДДДДДДДДДДДДДДДДДДЩ і ХННННё ГДДі tо ГДДДДДї і ФННННѕ і ЪДДДДДДДДДДДДДДДДДї ХННННё і ГДіконечное значениеГДі dо ГДДДї і ХННННННННё і АДДДДДДДДДДДДДДДДДЩ ФННННѕ і Аі dоwnto ГДДДЩ ЪДДДДДДДДДДДДДДДДДДДДДДДДДЩ ФННННННННѕ і ЪДДДДДДДДДДДДДДДДДї АДі оператор ГДДДДДДДДДД АДДДДДДДДДДДДДДДДДЩ ЪДДДДДДДДДДДДДДДДДДДДДДДДДДї управляющая переменная ДДі идентификатор переменной ГДДДДДД АДДДДДДДДДДДДДДДДДДДДДДДДДДЩ ЪДДДДДДДДДДДї начальное значение ДДДДДДі выражение ГДДДДДДДДДДДДДДДДДДДДД АДДДДДДДДДДДЩ ЪДДДДДДДДДДДї Конечное значение ДДДДДДДі выражение ГДДДДДДДДДДДДДДДДДДДДД АДДДДДДДДДДДЩ В качестве управляющей переменной должен использоваться идентификатор переменой (без какого-либо квалификатора), который обозначает переменную, объявленную локальной в блоке, в котором содержится оператор for. Управляющая переменная должна иметь пер ечислимый тип. Начальное и конечное значения должны иметь тип, совместимый по присваиванию с перечислимым типом. Когда начинает выполняться оператор for, начальное и конечное значения определяются один раз, и эти значения сохраняются на протяжении всего выполнения оператора for. Оператор, который содержится в теле оператора for, выполняется один раз для каждого значения в диапазоне между начальным и конечным значением. Управляющая переменная всегда инициализируется начальным значением. Когда работает оператор for, значение управляющей переменной (счетчика циклов) увеличивается при каждом повторении на единицу. Если начальное значение превышает конечное значение, то содержащийся в теле оператора 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 V := Expr1 downto Exp2 do Body; эквивалентен операторам: begin Temp1 := Expr1; Temp2 := Expr2; if Temp1 >= Temp2 then begin V := Temp1; Body; while V <> Temp2 o begin V := Pred(V); Body; end; end; end; где Temp1 и Temp2 - вспомогательные переменные, тип которых совпадает с основным типом переменной V и которые не встречаются в другом месте программы. Приведем примеры оператора цикла с параметром: 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 к полям одной или более конкретных переменных типа запись можно обращаться, используя только идентификаторы полей. Оперaтор with имеет следующий синтаксис: ХННННННё ЪДДДДДДДДДДДДДДДДДДДДї ХННННё оператор ДДДі with ГДДі ссылка на пере- ГДВДі dо ГДї with ФННННННѕ і менную типа запись і і ФННННѕ і і АДДДДДДДДДДДДДДДДДДДДЩ і і і ХННННё і і АДДДДДДДДДґ ; іДДДДДДДДЩ і ФННННѕ і ЪДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ і ЪДДДДДДДДДДДДДДДДДДї АДДі оператор ГДДДДДДД АДДДДДДДДДДДДДДДДДДЩ ЪДДДДДДДДДДДДДДДДДДДДДДї ссылка на переменную ДДДДДДі ссылка на переменную ГДДДДДДД типа запись АДДДДДДДДДДДДДДДДДДДДДДЩ или объектную переменную Приведем пример оператора with: with Date 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 и dо относится к переменной типа указатель, а в составном операторе x и y ссылаются на x.x и y.y. Оператор: with V1,V2,...Vn do s; эквивалентен операторам: with V1 do with V2 do ... with Vn do S; В обоих случаях, если Vn является полем и v1, и v2, то она интерпретируется как v2.Vn, а не как v1.Vn. Если выборка переменной типа запись связана с индексированием массива или разыменованием указателя, то эти действия производятся до того, как будет выполняться составной оператор. |