Связывание идентификатора объекта с его

Рис. 10. Присваивание указателей

ДОСТУП К ОБЪЕКТУ ЧЕРЕЗ УКАЗАТЕЛЬ. РАСКРЫТИЕ ССЫЛКИ.

Доступ к объекту через ограниченный указатель связан с предварительной установкой указателя на объект и последующим раскрытием ссылки. При этом имя указателя используется как идентификатор, за которым следует символ “ ^ ”, (т.е. калидент с постфиксом “^”). Доступ к объекту и его атрибутам осуществляется в несколько шагов:

¨ имя указателя – указатель используется для получения адреса того объекта, с которым он связан

¨ имя указателя^ - открывает доступ ко всему объекту, адрес которого хранится в указателе

¨ имя указателя^. - открывает доступ к атрибутам объекта

¨ имя указателя^. имя атрибута – открывает доступ к конкретному атрибуту объекта.

Каждый из подобных квалидентов открывает доступ к уникальному объекту или атрибуту объекта.

Var p: PCircle;

p { доступ к объекту ОКРУЖНОСТЬ }
p^.R { доступ к атрибуту РАДИУС объекта ОКРУЖНОСТЬ }
p^.Center.X { доступ к атрибуту X объекта ОКРУЖНОСТЬ }
p^.Center.Y { доступ к атрибуту Y объекта ОКРУЖНОСТЬ }

В общем случае размер объекта типа указатель, не равен размеру элемента хранения объекта, доступ к которому он открывает и не равен размеру атрибута объекта, т.е.

Sizeof(указатель) # Sizeof(указатель^) # Sizeof(указатель^.атрибут).

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

WITH < указатель^ > DO begin < присоединяемый фрагмент > end;

 
 


Var oc: Circle; p: PCircle;

begin

p:=addr(oc);

with p^ do begin

Center.X:=10; Center.Y:=20; R:=5

end;

Любое присоединение, объявленное оператором WITH, выполняется после того, как определено значение присоединяющего квалидента (другими словами, адреса того объекта, к атрибутам которого будет осуществляться доступ через указатель), т.е. до “входа” в обрабатываемый фрагмент. Изменение значения присоединяющего указателя внутри присоединяемого фрагмента не изменит уже созданного присоединения. Поэтому переустановка указателя, присоединяющего к обрабатываемому объекту, внутри присоединяемого фрагмента недопустима, а может выполняться только до оператора WITH. Правильный пример использования оператора присоединения приведен выше. Ошибочный пример следует далее:

Var oc1, oc2: Circle; p: PCircle;

begin

p: = @oc1;

with p^ do begin

p: = @oc2; { ошибка: переустановка указателя внутри

присоединяемого фрагмента }

p^. R: = ……

end;

Если два типизированных указателя указывают на разные объекты одного и того же типа, то одному объекту можно присвоить значения атрибутов другого объекта. Например:

Var p, q: PCircle;

Begin

p^. R:=5; p^. Center.X:=10; p^.Center.Y:=20; { * 1 * } q^:=p^; { * 2 * }

Выполнение операторов { * 1 * } и { * 2 * } иллюстрирует рис. 11.

     
 
 
 


Рис. 11. Выполнение операторов { * 1 * } и { * 2 * }

Оператор { * 2 * } эквивалентен следующей группе операторов:

q^.R:=p^.R; q^.Center.X:= p^.Center.X; q^.Center.Y:=p^.Center.Y;

Заметим, что с использованием присоединения эту группу операторов можно записать следующим образом:

with q^ do begin

R:=p^.R; Center.X:=p^.Center.X; Center.Y:=p^.Center.Y

end;

или

with p^ do begin

q^.R:=R; q^.Center.X:=Center.X; q^.Center.Y:=Center.Y

end;

После выполнения присваивания значения атрибутов первого и второго объекта становятся равными, а указатели по-прежнему указывают на разные объекты.

СРАВНЕНИЕ УКАЗАТЕЛЕЙ.

Указатели можно сравнивать между собой на равенство и неравенство. Два указателя считаются равными, если они указывают на один и тот же объект или оба никуда не указывают (оба равны NIL). Неравные указатели указывают на разные объекты или один из них никуда не указывает. Указатель можно сравнивать с константой NIL, чтобы узнать, ссылается ли данный указатель на конкретный объект. Порядок вычисления булевских выражений в условных операторах, использующих доступ к атрибутам объектов через указатели, очень важен. Например оператор:

If (p <> nil) and (p^. R = 10) then …

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

Оператор

If (p^. R = 10) and (p <> nil) then …

является некорректным, т.к. если p = nil, выражение p^. R = 10 не имеет смысла, поскольку указатель p ни на какой конкретный объект не указывает.


Понравилась статья? Добавь ее в закладку (CTRL+D) и не забудь поделиться с друзьями:  



double arrow
Сейчас читают про: