Указатели, процедурные и вариантные типы данных

Кроме рассмотренных выше простых и структурных типов данных, в языке Object Pascal имеется еще несколько типов данных, не относящихся ни к тем, ни к другим. Рассмотрим их.

Указатели

Указатель — это переменная, в которой хранится адрес памяти, указывающий на начало размещения некоторых данных в памяти.

Указатели применяют для определения адреса в памяти конкретного объекта, например какой-либо переменной.

Переменные типа "указатель" содержат и изменяют свои значения в процессе выполнения программы.

Указатели бывают типизированными и нетипизированными.

Типизированный указатель — это указатель, который ссылается на данные определенного типа и указан при объявлении указателя или типа указателя.

Для объявления типа указателя используется специальный значок ^, который располагается перед типом адресуемых данных.

Приведем пример объявления типизированного указателя:

var
X, Y: Integer ; / / X и Y переменные типа Integer
Р: ^Integer ; / / Р - указатель типа Integer

Нетипизированный указатель всегда имеет тип Pointer и ссылается на данные любого типа.

Пример объявления нетипизированного указателя:

var
Р: Pointer; / / Р - нетипизированный указатель типа Pointer

Рассмотрим пример использования указателей и поясним на этом примере операции, допустимые над указателями (листинг 2.2)

Листинг 2.2. Пример использований указателей

var
X, Y: Integer; / / объявление целых переменных X и Y Р: ^Integer; / / Р - указатель целого типа begin
X := 17; / / присваиваем значение переменной X Р := @Х ; / / присваиваем адрес переменной X указателю Р Y := Р^; / / разыменовываем указатель Р и присваиваем результат / / переменной Y
end;

Итак, для назначения указателю адреса объекта (в нашем случае — переменной х) мы воспользовались операцией @. Символ @, поставленный перед объектом, определяет адрес этого объекта в оперативной памяти.

Символ ^ имеет два назначения. Во-первых, если он стоит перед идентификатором типа, он обозначает тип данного указателя. Если же он стоит после переменной типа указателя, как в последней строке нашего примера, то он разыменовывает указатель. Операция разыменовывания указателя применяется для получения доступа к значению адресуемых данных.

После выполнения программы, представленной на листинге 2.2, обе переменные х и Y будут иметь одинаковое значение — 17.

Процедурные типы данных

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

Описание данных процедурного типа похоже на описание процедуры или функции. На листинге 2.3 представлено описание процедурных указателей.

Листинг 2.3. Описание процедурных указателей

type
TIntegerFunction = 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. Использование данных вариантного типа

var
V1, 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;

Переменная вариантного типа может принимать два дополнительных значения:

Hosted by uCoz