Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП / ООП_Лекции.doc
Скачиваний:
50
Добавлен:
08.06.2015
Размер:
1.03 Mб
Скачать

Операции с указателями

Для указателей PChar определены операции отношения =, <>, <, >, <=, >= . Кроме того для различных указателей определены еще следующие операции:

Обозна- чение

Операция

Типы операндов

Тип результата

Пример

+

сложение указателей

указатель на символ, целое

указатель на символ

Р + I

-

вычитание указателей

указатель на символ, целое

указатель на символ, целое

P-Q

^

разыменова­ние указателя

указатель

указатель на базовый тип

р^

=

равенство

указатель

Boolean

P = Q

<>

неравенство

указатель

Boolean

Р <> Q

Операнд операции разыменования ^ может быть указателем на любой тип. Указатель типа Pointer должен быть сначала пре­образован к конкретному типу, после чего его можно разымено­вывать.

Выражение Р = Q дает true только в случае, если Р и Q указы­вают на один адрес. В противном случае выражение Р <> Q дает true.

Операции + и — применяются для увеличения или уменьше­ния сдвига указателя на символ. Операция вычитания кроме того позволяет найти разность смещения двух указателей. Эти операции подчиняются следующим правилам.

Если I — целое число, а Р — указатель на символ, то Р + I уве­личивает на I адрес, на который указывает Р; т.е. возвращается указатель на адрес, отстоящий на I символов от Р. Аналогично, Р - I возвращается указатель на адрес, предшествующий Р на I символов.

Если Р и Q — указатели на символы, то Р - Q определяет чис­ло символов между Р и Q.

Операция @

Операция @ возвращает адрес своего операнда: переменной, функции, процедуры, метода. Иначе говоря операция @ создает указатель на свой операнд. При этом действуют следующие пра­вила:

• Если X — переменная, то @Х возвращает адрес X. Если вклю­чена директива компилятора {$Т-} (она включена по умолча­нию), то тип результата pointer. Если же включена директива {$Т+}, то тип результата ^Т, где Т — тип X.

• Если F — функция или процедура, то @F возвращает точку входа F, причем тип результата всегда pointer.

• При применении операции @ к методу перед идентификато­ром метода должна идти ссылка на имя класса, например, @TMyCIass.DoSomething.

Самоадресуемые записи

Нередко в памяти надо динамически размещать последовательность записей, как бы формируя некий фрагмент базы данных, предназначенный для оперативного ана­лиза и обработки. Поскольку динамическое размещение прово­дится в непредсказуемых местах памяти, то такие записи надо снабдить полями, содержащими указатели на следующую анало­гичную запись. Такие записи со ссылками на аналогичные запи­си и называются самоадресуемыми. Ниже приведена схема связи таких структур в последовательность. Полю указателя в послед­ней структуре обычно присваивается значение nil, что является признаком последней структуры при организации поиска в списке.

Приведем пример такой самоадресуемой структуры.

Type

trec=~rec;

rec=record

inl,in2:word ;

s:string[10];

pr:trec

end;

Подобное описание является исключением из общего правила языка Pascal, по которому нельзя использовать в предложениях еще не объявленные типы и переменные. В данном случае первое предложение объявляет тип trec как указатель на структуру типа rec, объявленного после этого. Сразу за этим предложением следует объявление самой структуры. В этом объявлении имеет­ся поле рг, представляющее собой указатель на структуру анало­гичного вида.

Приведем пример формирования в памяти списка таких структур. Для этого надо определить три переменные, являющи­еся указателями на структуры:

var РО : trec=nil;

Pnew, Pold: trec;

Первая из этих переменных будет всегда указывать на первую структуру в списке. Две остальные переменные — вспомогатель­ные. Если в некоторый момент возникла необходимость динами­чески разместить в памяти очередную структуру и вставить ее в конец списка, это можно сделать следующим кодом:

New (Pnew); { выделение памяти под новую запись }

with Pnew^ do { заполнение полей записи }

begin

in1:=…;

in2 :=...;

S:=…;

pr:=Nil;

end;

if P0=nil then PO:=Pnew { РО — указатель на первую запись }

else Pold^.pr :=Pnew ; { указатель на очередную запись }

Pold:=Pnew;

Если список еще не начат (РО = nil), то указателю РО присваи­вается ссылка на вновь размещенную структуру (Pnew). В про­тивном случае ссылка на новую структуру присваивается полю рг предыдущей структуре в списке (Pold). Таким образом новая структура включается в общий список. Полю рг этой структуры присваивается значение nil. Это является признаком того, что данная структура является последней в списке.

Сформировав список в памяти далее легко его просматривать, проходя в цикле по указателям. Легко также делать перестанов­ки записей, их удаление и т.п. Для всех этих операций не надо ничего перемещать в памяти. Достаточно только изменять соот­ветствующие ссылки в полях рг.

Раньше подобные списки широко использовались для созда­ния в памяти стеков, очередей и других упорядоченных списков. Однако, в Delphi введены специальные типы данных TList и TString , которые ведут подобные списки и имеют множество удобных методов для управления ими.

Соседние файлы в папке ООП