7.4.2. Указатели
Оперативная память ПК представляет
собой совокупность ячеек для хранения информации - байтов, каждый из которых
имеет собственный номер. Эти номера называются
адресами,
они позволяют
обращаться, к любому байту памяти. Object Pascal предоставляет в распоряжение
программиста гибкое средство управления динамической памятью - так называемые
указатели.
Указатель -
это переменная, которая в качестве своего значения
содержит адрес байта памяти. С помощью указателей можно размещать в динамической
памяти любой из известных в Object Pascal типов данных. Лишь некоторые из них
(Byte, Char, ShortInt, Boolean) занимают во внутреннем представлении один байт,
остальные - несколько смежных. Поэтому на самом деле указатель адресует лишь
первый байт данных.
Как правило, указатель связывается
с некоторым типом данных. Такие указатели будем называть
типизированными.
Для объявления типизированного указателя используется значок ^, который помещается
перед соответствующим типом, например:
var
p1 : ^Integer;
р2 : ^Real;
type
PerconPointer = "PerconRecord;
PerconRecord =
record
Name
: String;
Job
: String;
Next : PerconPointer ,
end;
Обратите внимание: при объявлении
типа PerconPointer мы сослались на тип PerconRecord, который предварительно
в программе объявлен не был. Как уже отмечалось, в Object Pascal последовательно
проводится в жизнь принцип, в соответствии с которым перед использованием какого-либо
идентификатора он должен быть описан. Исключение сделано только для указателей,
которые могут ссылаться на еще не объявленный тип данных.
В Object Pascal можно объявлять указатель
и не связывать его при этом с каким-либо конкретным типом данных. Для этого
служит стандартный тип pointer, например:
var
р: Pointer;
Указатели такого рода будем называть
нетипизированньти.
Поскольку нетипизированные указатели не связаны с
конкретным типом, с их помощью удобно динамически размещать данные, структура
и тип которых меняются в ходе работы программы.
Как уже говорилось, значениями указателей
являются адреса переменных в памяти, поэтому следовало бы ожидать, что значение
одного указателя можно передавать другому. На самом деле это не совсем так.
В Object Pascal можно передавать значения только между указателями, связанными
с одним и тем же типом данных.
Если, например,
var
pI1,pI2: ^integer;
pR: ^Real;
p: Pointer;
то присваивание
pI1 := pI2;
вполне допустимо, в то время как
pl1 :=pR;
запрещено, поскольку pI1 и pR указывают
на разные типы данных. Это ограничение, однако, не распространяется на нетипизированные
указатели, поэтому мы могли бы записать
p := pR;
pI1 := p;
и тем самым достичь нужного результата.