Оператор WITH

 

При работе с записями, при обращении к различным полям каждый раз приходится писать сначала имя самой записи, что не всегда удобно, если полей много. Поэтому в Паскале применяется оператор WITH:

with NEKTO do

begin

NAME := 'MANUELA'; AGE := 20;

MALADI := 'GRIP';

MARIE := true;

end.

Другими словами, в рамках оператора, помещенного внутри оператора WITH, к полям определенной переменной можно обращаться просто по имени (префикация имен опускается).

 

СИНТАКСИЧЕСКАЯ ДИАГРАММА

 

Особенно эффективно использовать WITH, когда речь идет о вложенных записях, т.е. таких, где поля есть тоже записи. Например, запись типа PATIENT можно расширить добавлением поля DATE, которое снова есть запись с 3-мя полями:

 

type PATIENT = record

NAME : string [10];

MALADI : string [30];

AGE : integer;

DATE : record

DEN : integer;

MESJATS : string [10];

GOD : integer;

end;

MARIE : boolean;

end;

var NEKTO : PATIENT.

 

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

read (NEKTO.DATE.GOD).

Здесь уже WITH может значительно упростить работу с полями:

with NEKTO, DATE do

begin

NAME := 'MANUELA'; AGE := 20;

MALADI := 'GRIP';

DEN := 18;

MESJATS := 'MART';

GOD := 1944;

MARIE := TRUE;

end.

 

Оператор WITH принято называть оператором присоединения. В общем случае он выглядит так: WITH R1, R2, ..., Rn do S , что эквивалентно WITH R1 do WITH R2, R3, ..., Rn do S.

Имя поля в операторе присоединения обозначает компоненту комбинированной переменной из ближайшего объединяющего оператора присоединения, в котором указана переменная с таким полем. Следовательно, если две переменные из списка комбинированных переменных оператора присоединения имеют поля, обозначенные одним и тем же именем, то внутри оператора WITH это имя обозначает поле той переменной, которая указана в списке позже.

С другой стороны, при определении некоторого комбинированного типа имена отдельных полей могут совпадать с именами обычных, простых переменных, не входящих в комбинированную переменную. Как здесь происходит отличие?

Пусть, например, имеется простая переменная AGE и поле AGE некоторой комбинированной переменной NEKTO. В этом случае их можно отличить, т.к. простая переменная имеет имя AGE, а переменная-поле имеет полное имя NEKTO.AGE. А что будет в операторе WITH, где префикс NEKTO опускается?

В этом случае в операторе предпочтение отдается именам полей записи, т.е. считается, что внутри оператора WITH соответствующее имя обозначает имя поля, а не имя переменной.

Проиллюстрируем этот тезис на примере. Пусть даны типы:

const N_STUD = ... ;

N_SOTR = ... ;

n = ... ;

type SEX = (M,F);

STUD = RECORD

FAM, IM, OTH : array [1..N_STUD] of string[n];

POL : SEX;

GR : 111..154;

STIP : boolean;

end;

SOTR = record

FAM, IM, OTH : array [1..N_SOTR] of string[n];

POL : SEX;

DOLGN : (LAB, ASS, STPR, DOZ, PROF);

ZARPL : integer;

end;

var X : STUD; Y : SOTR;

STIP : integer;

 

Тогда можно дать такой фрагмент программы:

with X, Y do

begin

IM[5] := 'ALEXANDR ';

POL := M;

STIP := true;

GR := 122;

end;

STIP := 160.

Здесь поля IM, POL относятся к переменной Y типа SOTR, т.к. эта переменная в списке переменных-записей заголовка WITH фигурирует после переменной X типа STUD. Кроме того, в этом фрагменте имя STIP в теле оператора WITH есть имя поля переменной Х.