|
ПРИСВАИВАНИЕ Присваивание для указателей сводится к пересылке значения одного указателя другому. Совместимыми по присваиванию являются: • два указателя одного и того же типа; • константа NIL и свободный указатель; • константа NIL и ограниченный указатель любого типа; • свободный указатель и ограниченный указатель любого типа. Ограниченному указателю одного типа можно присвоить значение ограниченного указателя другого типа с помощью функции приведения типов POINTER (но без крайней необходимости делать это не следует, т.к подобные действия приводят к нарушению строгой типизации). Каждый указатель перед использованием необходимо инициализировать, т.е. установить на соответствующий объект. Установка указателя на объект, адрес которого неизвестен, производится с помощью встроенной функции взятия адреса – Addr(), аргументом которой является идентификатор объекта. Эта функция возвращает результат типа Pointer, в котором содержится адрес аргумента. Аналогичный результат возвращает операция @. Установка указателя на объект, адрес которого известен и хранится в другом указателе, производится с помощью присваивания. Var pp, pp1, pp2: PPoint; pc: PCircle; p: Pointer; begin pp1:= pp; p:= pc; pp2:= nil; Результат выполнения этих операций иллюстрируется рис. 10. ДОСТУП К ОБЪЕКТУ ЧЕРЕЗ УКАЗАТЕЛЬ. РАСКРЫТИЕ ССЫЛКИ. Доступ к объекту через ограниченный указатель связан с предварительной установкой указателя на объект и последующим раскрытием ссылки. При этом имя указателя используется как идентификатор, за которым следует символ “^”, (т.е. калидент с постфиксом “^” ). Доступ к объекту и его атрибутам осуществляется в несколько шагов: • имя указателя – указатель используется для получения адреса того объекта, с которым он связан • имя указателя^ - открывает доступ ко всему объекту, адрес которого хранится в указателе • имя указателя^ . - открывает доступ к атрибутам объекта • имя указателя^ . имя атрибута – открывает доступ к конкретному атрибуту объекта. Каждый из подобных квалидентов открывает доступ к уникальному объекту или атрибуту объекта. В общем случае размер объекта типа указатель, не равен размеру элемента хранения объекта, доступ к которому он открывает и не равен размеру атрибута объекта, т.е. Sizeof( указатель ) # Sizeof( указатель^ ) # Sizeof( указатель^ .атрибут ). Для того чтобы сократить длину дистанции доступа при идентификации указанием, можно использовать оператор присоединения Любое присоединение, объявленное оператором WITH, выполняется после того, как определено значение присоединяющего квалидента (другими словами, адреса того объекта, к атрибутам которого будет осуществляться доступ через указатель), т.е. до “входа” в обрабатываемый фрагмент. Изменение значения присоединяющего указателя внутри присоединяемого фрагмента не изменит уже созданного присоединения. Поэтому переустановка указателя, присоединяющего к обрабатываемому объекту, внутри присоединяемого фрагмента недопустима, а может выполняться только до оператора WITH. Правильный пример использования оператора присоединения приведен выше. Ошибочный пример следует далее: Var oc1, oc2: Circle; p: PCircle; begin p: = @oc1; with p^ do begin p: = @oc2 ; { ошибка: переустановка указателя внутри присоединяемого фрагмента } p^. R: = …… 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 ни на какой конкретный объект не указывает.
|