Оператор 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 есть имя поля переменной Х.