Во многих задачах, особенно в задачах вычислительной математики, необходимо передавать имена подпрограмм в качестве параметров подпрограмм.Процедурные типы данных применяются для того, чтобы процедуры и функции можно было понимать как обычные значения, которые можно присваивать переменным и передавать в качестве параметров подпрограмм.
Процедурный тип определяется как заголовок процедуры и функции со списком формальных параметров, но без имени.
Если процедурный тип используется для хранения метода класса, то при описании типа необходимо указать of object.
Для переменных процедурного типа применима операция присваивания:
<имя_перем>:=<имя_подпр.>
<имя_перем> - имя переменной процедурного типа
<имя_подпр.> - имя подпрограммы с таким же заголовком, что и у процедурного типа.
Переменная процедурного типа фактически содержит адрес подпрограммы.
Для переменной процедурного типа применяется специальное значение Nil, которое означает, что переменная не содержит адреса подпрограммы.
Данные процедурного типа применяются, например, для назначения обработчиков события.
Иногда возникает необходимость работы с типами данных, которые не могут быть определены во время разработки приложения или тип которых изменяется. Для этого в язык Object Pascal были введены так называемые вариантные типы данных. Переменные вариантного типа могут содержать данные разных типов, кроме структурных типов данных, указателей и типа Int64. Для объявления переменной вариантного типа используется слово variant. Все типы являются совместимыми с типом variant, и компилятор делает необходимые преобразования типов автоматически.
Переменная вариантного типа может принимать два дополнительных значения:
Unassigned - не определено;
Null - значение неизвестного типа или значение потеряно.
Пример
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;
Указатель - это переменная, в которой хранится адрес памяти, указывающий на начало размещения некоторых данных в памяти.
Указатели применяют для определения адреса в памяти конкретного объекта, например какой-либо переменной или подпрограммы.
Указатели бывают типизированными и нетипизированными.
Типизированный указатель — это указатель, который ссылается на данные определенного типа и указан при объявлении указателя или типа указателя.
Для объявления типа указателя используется специальный значок ^, который располагается перед типом адресуемых данных.
Type
<имя_типа>=^<тип_данных>;
Нетипизированный указатель — это указатель, который содержит адрес произвольной области памяти, то есть ссылается на данные любого типа.
Для объявления нетипизированного указателя используется слово pointer.
Для получения адреса переменной или подпрограммы используется операция получения адреса @ или стандартная функция addr(X).
Для указателя применяется специальное значение Nil, которое означает, что указатель не содержит адреса.
Для доступа к переменной, адрес которой находится в указателе, используется операция разыменовывания указателя ^.
Для указателей применимы операции отношения = и <>.