Для указателей действуют гораздо более жесткие правила совместимости типов, чем для обычных переменных. В операции присваивания могут фигурировать только указатели, адресующие переменные одинаковых типов данных. Нельзя, скажем, записать:
p:= q; {p:= ^integer; q: ^byte;}Обойти эти ограничения позволяет универсальность нетипизированного указателя pointer, совместимого с указателями любых типов:
{p:= ^integer; q: ^byte; t: pointer;} t:= q; p:= t;У указателей также существует свой "ноль", который означает, что указатель не указывает никуда:
p:= nil;Замечание: Если указатель не хранит конкретного адреса (его значение не определено), то это вовсе не означает, что он никуда не указывает. Скорее всего, он все-таки указывает, но только в какую-нибудь неожиданную (хорошо, если не системную) область памяти.
Сравнение адресов
Для указателей определены две операции сравнения: = и <>.
Две переменные, описанные как указатели на один и тот же тип данных, считаются совпадающими, если они указывают на одну и ту же область памяти.
Для разнотипных указателей сравнения невозможны: попытка записать
if p = q then writeln('yes'); {p: ^byte; q: ^integer;}вызовет ошибку уже на этапе компиляции.
Однако сравнивать типизированный и нетипизированный указатели можно.
Операция разыменования
Для того чтобы воспользоваться значением, хранящимся по некоторому адресу, необходимо его оттуда "извлечь". Унарная операция ^ называется разыменованием и записывается по следующему шаблону:
<имя указателя>^Результатом операции ^ является значение, хранящееся по указанному адресу. Тип этого значения будет определяться типом (типизированного) указателя. К нетипизированным указателям операцию разыменования применять нельзя.
type
zap=record ves:integer;…end;
mas=array[0..9] of word;
var
pch: ^ char;
pzap: ^ zap;
pmas: ^ mas;
-------------------------------------------
pch^:=’!’;{ обращение к динамической переменной типа char}
read(pzap^.ves); { обращение к полю динамической записи}
write(pmas[0]^);{ обращение к элементу динамического массива}
--------------------------
Фактически можно говорить, что pch^, pzap^.ves, pmas[0]^ это имена динамических объектов в программе, адреса которых хранятся в указателях pch, pzap, pmas.
Обращение к var типа pointer указывает на неопределенный тип. Его нельзя связывать с конкретным типом данных.
Var
P:pointer;
P1:^real;
P2:^integer;
----------
P:=p1;
P2:=p;
p^:=1; {нельзя!}