Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Руководство по языку Паскаль 1.doc
Скачиваний:
12
Добавлен:
22.04.2019
Размер:
2.48 Mб
Скачать

Глава 7. Операторы

─────────────────────────────────────────────────────────────────

Операторы описывают те алгоритмические действия, которые

должны выполняться. Операторам могут предшествовать метки, кото-

рые можно использовать для ссылок в операторах перехода goto.

оператор ──┬────────────────────┬──────────────────────────>

│ ┌─────┐ ┌───┐ ^ │ ┌────────────────┐ ^

└─>│метка├──>│ : ├─┘ ├──>│простой оператор├──┤

└─────┘ └───┘ │ └────────────────┘ │

│ ┌────────────────┐ │

└──>│ структурный ├──┘

│ оператор │

└────────────────┘

Метка - это последовательность цифр в диапазоне от 0 до 9999

или идентификатор.

Существует два основных вида операторов: простые операторы и

структурные операторы.

Простые операторы

─────────────────────────────────────────────────────────────────

Простым оператором является такой оператор, который не со-

держит в себе других операторов.

┌─────────────────────┐

простой оператор ────┬───>│оператор присваивания├───────>

│ └─────────────────────┘ ^

│ ┌─────────────────────┐ │

├───>│ оператор процедуры ├───┤

│ └─────────────────────┘ │

│ ┌─────────────────────┐ │

└───>│ оператор перехода ├───┘

└─────────────────────┘

B.Pascal 7 & Objects/LR - 118 -

Оператор присваивания

─────────────────────────────────────────────────────────────────

Оператор присваивания заменяет текущее значение переменной

новым значением, которое определяется выражением, или определяет

выражение, значение которого должно возвращаться функцией.

┌───────────┐ ┌──┐ ┌─────────┐

оператор ─────┬──>│ссылка на ├──────>│:=├──>│выражение├──>

присваивания │ │переменную │ ^ └──┘ └─────────┘

│ └───────────┘ │

│ ┌─────────────┐ │

└──>│идентификатор├─┘

│ функции │

└─────────────┘

Выражение должно быть совместимо по присваиванию с типом пе-

ременной или типом значения, возвращаемого функцией в качестве

результата (см. раздел "Совместимость типов" в Главе 4).

Приведем некоторые примеры операторов присваивания:

X := Y + Z

Done := (I >= 1) and (I < 100);

Huel := [blue, Succ(C)];

I := Sqr(J) - I * K;

Присваивания объектного типа

Правила совместимости по присваиванию объектных типов позво-

ляют присваивать экземпляру объекта экземпляр любого из его до-

черних типов. Такое присваивание представляет собой проекцию

потомка на пространство его предка. В примере исходного кода в

Главе 4 с учетом экземпляра F типа TField и экземпляра Z типа

TZipField присваивание F := Z копирует только поля X, Y, Len и

Name.

Присваивание экземпляру объектного типа не инициализирует

экземпляр. Например, в предыдущем примере присваивание F := Z оз-

начает, что вызов конструктора для F можно опустить.

B.Pascal 7 & Objects/LR - 119 -

Операторы процедуры

─────────────────────────────────────────────────────────────────

Оператор процедуры определяет активизацию процедуры, обозна-

ченную с помощью идентификатора процедуры. Если соответствующее

описание процедуры содержит список формальных параметров, то опе-

ратор процедуры должен содержать в себе соответствующий ему спи-

сок фактических параметров (параметры, список которых приводится

в определении, являются формальными параметрами, а в операторе

вызова процедуры они являются фактическими параметрами). При вы-

зове происходит передача фактических параметров формальным пара-

метрам.

┌─────────────┐

оператор ──┬─>│идентификатор├─┬┬──────────────────────────>

процедуры │ │ процедуры │ ││ ┌──────────────────┐ ^

│ └─────────────┘ │└─>│список фактических├─┘

│ ┌─────────────┐ │ │ параметров │

├─>│ десигнатор ├─┤ └──────────────────┘

│ │ метода │ │

│ └─────────────┘ │

│ ┌─────────────┐ │

├─>│ уточненный ├─┤

│ │ десигнатор │ │

│ │ метода │ │

│ └─────────────┘ │

│ ┌─────────────┐ │

└─>│ ссылка на ├─┘

│ переменную │

└─────────────┘

Приведем некоторые примеры операторов процедур:

PrintHeaing;

Transpose(A,N,M);

Fin(Name,Address);

B.Pascal 7 & Objects/LR - 120 -

Операторы перехода

─────────────────────────────────────────────────────────────────

Оператор перехода goto вызывает передачу управления операто-

ру, которому предшествует метка, указанная в данном операторе пе-

рехода. Синтаксическая схема оператора перехода имеет следующий

вид:

┌────┐ ┌─────┐

оператор перехода ───>│goto├───>│метка├───>

└────┘ └─────┘

При использовании оператора перехода должны соблюдаться сле-

дующие правила:

1. Метка, которая указывается в операторе перехода, должна

находиться в том же блоке или модуле, что и сам оператор

перехода. Другими словами, не допускаются переходы из

процедуры или функции или внутрь нее.

2. Переход извне внутрь структурного оператора (то есть пе-

реход на более глубокий уровень вложенности) может выз-

вать непредсказуемые эффекты, хотя компилятор не выдает

сообщения об ошибке. Например, вы не должны переходить в

тело цикла for.

Примечание: Хорошая практика программирования требует

минимального использования переходов.

Структурные операторы

─────────────────────────────────────────────────────────────────

Структурные операторы строятся из других операторов, порядок

выполнения которых должен быть последовательным (составные опера-

торы и операторы над записями), определяемым условной передачей

управления (условные операторы) или повторяющимся (операторы цик-

ла).

┌───────────────────────┐

структурный ────┬────>│ составной оператор ├───────>

оператор │ └───────────────────────┘ ^

│ ┌───────────────────────┐ │

├────>│ условный оператор ├───┤

│ └───────────────────────┘ │

│ ┌───────────────────────┐ │

├────>│ оператор цикла ├───┤

│ └───────────────────────┘ │

│ ┌───────────────────────┐ │

└────>│ оператор над записями ├───┘

└───────────────────────┘

B.Pascal 7 & Objects/LR - 121 -

Составные операторы

─────────────────────────────────────────────────────────────────

Составные операторы задают порядок выполнения операторов,

являющихся их элементами. Они должны выполняться в том порядке, в

котором они записаны. Составные операторы обрабатываются, как

один оператор, что имеет решающее значение там, где синтаксис

Паскаля допускает использование только одного оператора. Операто-

ры заключаются в ограничители begin и end, и отделяются друг от

друга точкой с запятой.

┌─────┐ ┌────────┐ ┌───┐

составной ────>│begin├──────>│оператор├────┬──>│end├──>

оператор └─────┘ ^ └────────┘ │ └───┘

│ ┌───┐ │

└─────┤ ; │<──────┘

└───┘

Приведем пример составного оператора:

begin

Z := X;

X := Y;

Y := Z;

end;

Условные операторы

─────────────────────────────────────────────────────────────────

Условные операторы позволяют выбрать для выполнения один из

составных операторов (или не выбрать ни одного).

┌───────────────┐

условный оператор ──┬──>│ оператор if ├───────>

│ └───────────────┘ ^

│ ┌───────────────┐ │

└──>│ оператор case ├───┘

└───────────────┘

B.Pascal 7 & Objects/LR - 122 -

Оператор условия (if)

─────────────────────────────────────────────────────────────────

Синтаксис оператора if можно представить следующим образом:

┌──┐ ┌─────────┐ ┌────┐ ┌────────┐

оператор if ─>│if├──>│выражение├──>│then├──>│оператор├──┬──┐

└──┘ └─────────┘ └────┘ └────────┘ │ │

┌────────────────────────┘ │

│ ┌────┐ ┌────────┐ v

└──>│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 двоеточие

не указывается.

В общем случае ключевое слово else связывается с ближайшим

ключевым словом if, которое еще не связано с ключевым словом

else.

Приведем два примера оператора if:

if X < 1.5 then

Z := X+Y

else

Z := 1.5;

if P1 <> nil then

P1 := P1^.father;

B.Pascal 7 & Objects/LR - 123 -

Оператор варианта (case)

─────────────────────────────────────────────────────────────────

Оператор варианта (casе) состоит из выражения (переключате-

ля) и списка операторов, каждому из которых предшествует одна или

более констант (они называются константами выбора) или ключевое

слово else. Переключатель (селектор) должен иметь порядковый тип

(размером в байт или слово). Таким образом, строковый тип и длин-

ный целый тип являются недопустимыми типами переключателя. Все

константы выбора должны быть уникальными и иметь порядковый тип,

совместимый с типом переключателя.

┌────┐ ┌─────────┐ ┌──┐ ┌────┐

оператор case ─>│case├──>│выражение├──>│of├─────>│case├──┬──┐

└────┘ └─────────┘ └──┘ ^ └────┘ │ │

│ ┌────┐ │ │

└───┤ ; │<─┘ │

└────┘ │

┌───────────────────────────────────────┘

│ ┌───┐

└─┬────────────────────┬──────────>│end├──>

│ ┌──────────┐ ^ │ ┌───┐ ^ └───┘

└──>│ветвь else├──┘ └─>│ ; ├──┘

└──────────┘ └───┘

┌────────────────────┐

┌─────────┐ │ ┌──┐ ┌─────────┐ v ┌───┐ ┌────────┐

case ──>│константа├─┴─>│..├─>│константа├──┬─>│ : ├─>│оператор├─>

^ └─────────┘ └──┘ └─────────┘ │ └───┘ └────────┘

│ ┌───┐ │

└─────────────────┤ , │<─────────────┘

└───┘

┌────┐ ┌────────┐

ветвь else ────>│else├───>│оператор├───>

└────┘ └────────┘

Оператор варианта case приводит к выполнению оператора, ко-

торому предшествует константа выбора, равная значению переключа-

теля или диапазону выбора, в котором находится значение переклю-

чателя. Если такой константы выбора или такого диапазона выбора

не существует и присутствует ветвь else, то выполнятся оператор,

следующий за ключевым словом else. Если же ветвь else отсутству-

ет, то никакой оператор не выполняется.

B.Pascal 7 & Objects/LR - 124 -

Приведем некоторые примеры оператора варианта:

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;

B.Pascal 7 & Objects/LR - 125 -

Оператор цикла

─────────────────────────────────────────────────────────────────

Оператор цикла задает повторное выполнение определенных опе-

раторов.

┌─────────────────┐

оператор цикла ───┬──>│ оператор repeat ├──────>

│ └─────────────────┘ ^

│ ┌─────────────────┐ │

├──>│ оператор while ├──┤

│ └─────────────────┘ │

│ ┌─────────────────┐ │

└──>│ оператор for ├──┘

└─────────────────┘

Если число повторений заранее известно, то подходящей конс-

трукций является оператор for. В противном случае следует исполь-

зовать операторы while или repeat.

Для управления повторением операторов можно использовать

стандартные процедуры Break и Continue. Break завершает оператор

цикла, а Continue продолжает со следующей итерации этого операто-

ра. Подробности вы можете найти в Главе 1 "Справочного руководс-

тва программиста".

Оператор цикла с постусловием (repeat)

─────────────────────────────────────────────────────────────────

В операторе цикла с постусловием (начинающимся со слова

repeat) выражение, которое управляет повторным выполнением после-

довательности операторов содержится внутри оператора repeat.

┌──────┐ ┌────────┐ ┌─────┐ ┌─────────┐

оператор ─>│repeat├────>│оператор├──┬─>│until├──>│выражение├──>

repeat └──────┘ ^ └────────┘ │ └─────┘ └─────────┘

│ ┌───┐ │

└────┤ ; │<────┘

└───┘

Результат выражения должен быть булевского типа. Операторы,

заключенные между ключевыми словами repeat и until, выполняются

последовательно до тех пор, пока результат выражения не примет

значение True. Последовательность операторов выполнится по край-

ней мере один раз, поскольку вычисление выражения производится

после каждого выполнения последовательности операторов.

B.Pascal 7 & Objects/LR - 126 -

Приведем примеры оператора цикла с постусловием:

repeat

K := I mod J;

I := J;

J := K;

until J = 0;

repeat

Write('Введите значение (0..9):');

Readln(I);

until (I >= 0) and (I <= 9);

B.Pascal 7 & Objects/LR - 127 -

Операторы цикла с предусловием (while)

─────────────────────────────────────────────────────────────────

Оператор цикла с предусловием (начинающийся с ключевого сло-

ва while) содержит в себе выражение, которое управляет повторным

выполнением оператора (который может быть составным оператором).

┌─────┐ ┌─────────┐ ┌──┐ ┌────────┐

оператор ───>│while├──>│выражение├──>│do├──>│оператор├──>

while └─────┘ └─────────┘ └──┘ └────────┘

Выражение, с помощью которого осуществляется управление пов-

торением оператора, должно иметь булевский тип. Вычисление его

производится до того, как внутренний оператор будет выполнен.

Внутренний оператор выполнятся повторно до тех пор, пока выраже-

ние принимает значение Т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;

B.Pascal 7 & Objects/LR - 128 -

Операторы цикла с параметром (for)

─────────────────────────────────────────────────────────────────

Операторы цикла с параметром (которые начинаются со слова

for) вызывает повторяющееся выполнение оператора (который может

быть составным оператором) пока управляющей переменной присваива-

ется возрастающая последовательность значений.

┌───┐ ┌───────────┐ ┌──┐ ┌────────┐

оператор ───>│for├──>│управляющая├──>│:=├──>│исходное├───┐

for └───┘ │переменная │ └──┘ │значение│ │

└───────────┘ └────────┘ │

┌────────────────────────────────────────────────┘

│ ┌──┐

│ ┌─>│to├─────┐ ┌────────┐ ┌──┐ ┌────────┐

└───┤ └──┘ ├──>│конечное├──>│do├──>│оператор├───>

│ ┌──────┐ │ │значение│ └──┘ └────────┘

└─>│downto├─┘ └────────┘

└──────┘

┌────────────────────────┐

управляющая переменная ───>│идентификатор переменной├───>

└────────────────────────┘

┌─────────┐

исходное значение ────>│выражение├───>

└─────────┘

┌─────────┐

конечное значение ────>│выражение├───>

└─────────┘

В качестве управляющей переменной должен использоваться

идентификатор переменой (без какого-либо квалификатора), который

обозначает переменную, объявленную локальной в блоке, в котором

содержится оператор for. Управляющая переменная должна иметь пе-

речислимый тип. Начальное и конечное значения должны иметь тип,

совместимый по присваиванию с перечислимым типом.

Примечание: О локальности и области действия рассказы-

вается в Главе 8.

Когда начинает выполняться оператор for, начальное и конеч-

ное значения определяются один раз, и эти значения сохраняются на

протяжении всего выполнения оператора for.

Оператор, который содержится в теле оператора for, выполня-

ется один раз для каждого значения в диапазоне между начальным и

конечным значением. Управляющая переменная всегда инициализирует-

ся начальным значением. Когда работает оператор for, значение уп-

равляющей переменной (счетчика циклов) увеличивается при каждом

повторении на единицу. Если начальное значение превышает конечное

значение, то содержащийся в теле оператора for оператор не выпол-

B.Pascal 7 & Objects/LR - 129 -

нятся. Когда в операторе цикла используется ключевое слово

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;

B.Pascal 7 & Objects/LR - 130 -

где 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);

B.Pascal 7 & Objects/LR - 131 -

Оператор with

─────────────────────────────────────────────────────────────────

В операциях над записями оператор with удобно использовать

для краткого обращения к полям записи. В операторе with к полям

одной или более конкретных переменных типа запись можно обращать-

ся, используя только идентификаторы полей. Оперaтор with имеет

следующий синтаксис:

┌────┐ ┌───────────────┐ ┌──┐ ┌────────┐

оператор ──>│with├─────>│ ссылка на ├──┬─>│do├──>│оператор├>

with └────┘ ^ │переменную типа│ │ └──┘ └────────┘

│ │ запись │ │

│ │ или объект │ │

│ └───────────────┘ │

│ ┌───┐ │

└────────┤ , │<────────┘

└───┘

ссылка на переменную ┌────────────────────┐

типа запись или объект ───>│ссылка на переменную├──>

└────────────────────┘

Возьмем следующее описание:

type

TDate = record

Day : Integer:

Month : Integer;

Year : Integer:

end;

var OrderDate: TDate;

С учетом данного описания приведем пример оператора with:

with OrderDate do

if Month = 12 then

begin

Month := 1;

Year := Year + 1

end else

Month := Month + 1;

Это эквивалентно следующему:

if OrderDate.Month = 12 then

begin

OrderDate.Month := 1;

OrderDate.Year := TDate.Year + 1

end

else

Date.month := TDate.Month + 1;

B.Pascal 7 & Objects/LR - 132 -

В операторе with сначала производится проверка каждой ссылки

на переменную, а именно: можно ли ее интерпретировать, как поле

записи. Если это так, то она всегда интерпретируется именно таким

образом, даже если имеется доступ к переменной с тем же именем.

Допустим описаны следующие переменные:

type

TPoint = 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.

Если выборка переменной типа запись связана с индексировани-

ем массива или разыменованием указателя, то эти действия произво-

дятся до того, как будет выполняться составной оператор.

B.Pascal 7 & Objects/LR - 133 -

───────────────────────────────────────────────────────────────────────

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]