Указатели,
процедурные и вариантные типы данных
Кроме рассмотренных выше
простых и структурных типов данных, в языке Object Pascal имеется еще несколько
типов данных, не относящихся ни к тем, ни к другим. Рассмотрим их.
Указатели
Указатель — это
переменная, в которой хранится адрес памяти, указывающий на начало размещения
некоторых данных в памяти.
Указатели применяют для
определения адреса в памяти конкретного объекта, например какой-либо переменной.
Переменные типа "указатель"
содержат и изменяют свои значения в процессе выполнения программы.
Указатели бывают типизированными
и нетипизированными.
Типизированный указатель
— это указатель, который ссылается на данные определенного типа и указан
при объявлении указателя или типа указателя.
Для объявления типа указателя
используется специальный значок ^, который располагается перед типом адресуемых
данных.
Приведем пример объявления
типизированного указателя:
var
X, Y: Integer ; / / X и Y переменные типа Integer
Р: ^Integer ; / / Р - указатель типа Integer
Нетипизированный
указатель всегда имеет тип Pointer
и ссылается на данные любого
типа.
Пример объявления нетипизированного
указателя:
varР: Pointer; / / Р - нетипизированный указатель типа Pointer
Рассмотрим
пример использования указателей и поясним на этом примере операции, допустимые
над указателями (листинг 2.2)
Листинг 2.2. Пример
использований указателей
varX, Y: Integer; / / объявление целых переменных X и Y Р: ^Integer; / / Р - указатель целого типа begin
end;
X := 17; / / присваиваем значение переменной X Р := @Х ; / / присваиваем адрес переменной X указателю Р Y := Р^; / / разыменовываем указатель Р и присваиваем результат / / переменной Y
Итак, для назначения указателю
адреса объекта (в нашем случае — переменной х) мы воспользовались операцией
@. Символ @, поставленный перед объектом, определяет адрес этого объекта в оперативной
памяти.
Символ ^ имеет два назначения.
Во-первых, если он стоит перед идентификатором типа, он обозначает тип
данного указателя. Если же он стоит после переменной типа указателя,
как в последней строке нашего примера, то он разыменовывает указатель. Операция
разыменовывания указателя применяется для получения доступа к значению адресуемых
данных.
После выполнения программы,
представленной на листинге 2.2, обе переменные х и Y будут иметь одинаковое
значение — 17.
Процедурные типы данных
Процедурные типы данных
применяются для того, чтобы можно было процедуры и функции понимать как
обычные значения, которые можно присваивать переменным, или выполнять с ними
различные действия.
Описание данных процедурного
типа похоже на описание процедуры или функции. На листинге 2.3 представлено
описание процедурных указателей.
Листинг 2.3. Описание
процедурных указателей
typeTIntegerFunction = function: Integer; TProcedure = procedure; TStrProc = procedure(const S: string); TMathFunc = function (X: Double): Double; var
F: TIntegerFunction; / / F - это функция без параметров, которая
/ / возвращает целое число
Proc: TProcedure; / / Proc - это процедура без параметров SP: TStrProc; / / SP - это процедура, у которой есть один
/ / строковый параметр М: TMathFunc; / / М - это функция с действительным параметром
/ данная функция возвращает действительное значение
/
Для описания данных процедурного
типа используется конструкция of object.
Например:
type
TMethod = procedure of object;
TNotifyEvent = procedure(Sender: TObject) of object;
Данные процедурного типа
применяются, например, для назначения обработчиков события.
Вариантные типы данных
Иногда возникает необходимость
работы с типами данных, которые не могут быть определены во время разработки
приложения или тип которых изменяется. Для этого в язык Object Pascal были введены
так называемые вариантные типы данных. Переменные вариантного типа могут
содержать данные разных типов, кроме структурных типов данных, указателей и
типа Int64. Для объявления переменной вариантного типа используется слово variant.
Все типы являются совместимыми с типом variant, и компилятор делает необходимые
преобразования типов автоматически.
Пример, приведенный на
листинге 2.4, показывает применение вариантного типа данных.
Листинг 2.4. Использование
данных вариантного типа
varV1, V2, V3, V4, V5: Variant; I: Integer;
D: Double; S: string; begin V1 := 1; / / целое значение
V2 := 1234.5678; / / действительное значение
V3 := 'Это строка!'; / / строковое значение
V4 := '1000'; / / строковое значение
V5 := V1 + V2 + V4; / / действительное значение, равное 2235.5678 I := V1; / / I=1 (целое значение)D := V2; / / D = 1234.5678 (действительное значение)
S := V3; / / S = 'Это строка!' (строковое значение)
I := V4; / / I = 1000 (целое значение)
S := V5; / / S = '2235.5678' (строковое значение) end;
Переменная вариантного
типа может принимать два дополнительных значения:
Unassigned
—
не определено; Null
—
значение неизвестного типа или значение потеряно.