Если мы хотим указать в программе на значение по указанному в переменной типа Pointer адресу, то мы должны использовать символ «^» после имени указателя, например: Р^. Это есть операция разыменования. Подробно этот вопрос рассмотрен при описании работы со ссылками, а особенности разыменования указателей обсуждаются вместе с работой функции Ptr.
10.5. Средства для работы с адресами
В разд. 10.3 были рассмотрены средства анализа расположения частей работающей программы. Обсудим инструментарий, применимый к данным, используемых программой. Это операции достаточно низкого уровня, но некоторые из рассматриваемых здесь функций можно с успехом применять и на более высоком уровне, в частности при работе с ссылками и динамическими данными. Список таких функций приведен в табл. 10.2.
Таблица 10.2
Функция : Тип -- Возвращаемое значение
Addr(X) : Pointer -- Ссылка на начало объекта X в памяти
Seg(X) : Word -- Сегмент, в котором хранится объект X
Ofs(X) : Word -- Смещение в сегменте для объекта X
Prt(S, O : Word) : Pointer -- Ссылка на место в памяти, заданное значениями смещения O и сегмента S
SizeOf(X) : Word -- Размер объекта X в байтах
Операция @X : Pointer -- Возвращает ссылку на начало объекта X памяти (аналог функции Addr)
10.5.1. Определение адреса переменных
Функции Addr(X), Seg(X) и Ofs(X), а также оператор @ возвращают адрес объекта X или компоненты адреса. Под X можно понимать любой объект: переменные любых типов, объекты, процедуры и функции (но не константы).
Функция Addr(X) и оператор @ возвращают значение типа Pointer — адрес объекта X. Их действие одинаково:
VAR
X : String; p, q : Pointer;
...
р: = Addr( X );
q: = @X;
{Теперь p=q, и адреса равны; они указывают на один объект }
Значение типа Pointer не может быть выведено на экран. Но так как этот тип состоит из двух слов (Word), хранящих сегмент и смещение, можно вывести их в отдельности, используя функции Seg и Ofs (обе типа Word):
WriteLn( 'Сегмент ', Seg( р ), ' смещение ', Ofs( р ));
В то же время значения ссылок можно получить в режиме отладки. Они будут выводиться в окна наблюдения и модификации (Watch и Evaluate).
Может возникнуть вопрос — а зачем вообще нужна функция Addr, если есть Seg и Ofs, тем более что нельзя распечатать ее значение? Ответ: функция Addr и оператор @ нужны для привязывания ссылок, т.е. динамических переменных, к статическим данным, а также для работы с массивами данных в виде OBJ-файлов, связанных с выполнимым файлом на этапе компоновки. Пример компоновки внешних данных дан при описании работы с образом экрана на диске в разд. 20.4 «Работа с образом экрана на диске».