Процедурный тип данных в Object Pascal позволяет трактовать процедуры и функции в качестве значений, которые можно присваивать переменным и передавать в качестве параметров.
В Object Pascal существует два процедурных типа: тип-процедура и тип-функция.
Для объявления процедурного типа используется заголовок процедуры (функции), в котором опускается ее имя, например:
Type
ProcType1 = Procedure(a, b, с: Real; vard: Real);
ProcType2 = Procedure(var a, b);
РгосTypeЗ = Procedure;
FuncType1 = Function: String;
FuncType2 = Function (var s: String):Real;
В программе могут быть объявлены переменные процедурных типов, например:
Var
p1 : ProcType1;
fl, f2 : FuncType2;
ар : array[1..N] ofProcType2;
Переменным процедурных типов допускается присваивать в качестве значений имена соответствующих подпрограмм. После такого присваивания имя переменной становится синонимом имени подпрограммы.
Передаваемые в подпрограммы в качестве параметров процедуры или функции не могут быть локальными, т.е. не могут быть объявленными внутри другой подпрограммы.
Процедурные типы совместимы друг с другом при выполнении следующих условий:
· оба процедурных типа имеют одинаковое количество параметров;
· параметры занимают одинаковые позиции и имеют один тип – для совместимости имена параметров не играют никакой роли;
· любой процедурный тип совместим со значением nil.
Тип вариант: variant
Тип variant (вариант) разработан специально для тех случаев, когда на этапе написания и компиляции программы не известно какого типа данные будут использоваться в выражении или как параметры вызова подпрограмм. Переменная-вариант занимает в памяти дополнительные 2 байта, в которые помещается информация о действительном типе переменной. Эта информация позволяет компилятору создать код, который будет осуществлять необходимое преобразование типов на этапе прогона программы.
Свойства варианта
В переменную-вариант можно поместить:
· целое или вещественное число;
· логическое значение;
· строку;
· время и/или дату;
· OLE-объект;
· массив произвольной размерности и длины, содержащий элементы одного из перечисленных выше типов.
Варианты могут участвовать в целочисленных, вещественных, логических и время-дата выражениях при условии корректности соответствующих преобразований. Например, если варианту v присвоена строка '1.0', то выражение 1+v будет правильным вещественным значением 2,0. Однако если v := 'текст', выражение 1+v вызовет ошибку (исключение) EVariantError (см. раздел 3.18.).
Любая переменная вариантного типа представляет собой 16-байтную запись, содержащую 8-байтную вариантную часть, которая хранит либо собственно данные, либо их адрес (т.е. указатель – см. раздел 3.17.).
В Object Pascal начиная с версии Delphi 6 появились так называемые пользовательские варианты, которые фактически снимают ограничения на характер значений варианта.
Подпрограммы для работы с вариантами
Для работы с вариантами необходимо в разделе описания внешних модулей подключать модуль variants. Подпрограммы, используемые для операций над вариантами представлены в таблице 3.11.
Таблица 3.11.Процедуры и функции для операций над вариантами
Function VarFromDateTime
(DateTime: TDateTime):Variant;
Возвращает вариант, содержащий данные DateTime типа дата-время
Function VarIsEmpty(const V:
Variant): Boolean;
Возвращает True, если вариант V не содержит данных
Function VarIsNull
(const V: Variant) : Boolean;
Возвращает True, если вариант V содержит данные неопределенного типа (varNull),
Function VarToDateTime
(const V:Variant ): TDateTime);
Преобразует данные варианта V к типу дата-время
Function VarToStr
(const V: Variant) : String;
Преобразует данные варианта V к строке
Function VarType
(const V: Variant) : Integer;
Возвращает тип хранящихся в варианте данных
Вариантные массивы
Значением варианта может быть массив данных, такие варианты называются вариантными массивами. (Не путать с обычным или динамическим массивом, элементами которого являются варианты!) Значениями элементов вариантного массива могут быть любые допустимые для варианта значения, кроме строк varstring. Значениями элементов вариантного массива могут быть и варианты, а это значит, что в таком массиве могут одновременно храниться данные разных типов (в том числе и строки). Например:
Uses
variants;
Var
V: Variant;
Begin
{Создаем одномерный вариантный массив с 5 элементами и
наполняем его}
V := VarArrayCreate([0, 4], varVariant);
V[0] := 1; {целый тип}
V[1] := 1234.5678; {вещественный тип }
V[2] := ’Hello world’; {строковый тип}
V[3] := True; {логический тип}
{Пятым элементом исходного массива сделаем еще один
массив}
V[4] := VarArrayOf([1, 10, 100, 1000]);
writeln(V[2]); {Hello world}
writeln(3*V[4][2]); {300}
End.
Все действия с вариантными массивами осуществляются с помощью процедур и функций, приведенный в таблице 3.12.
Таблица 3.11.Процедуры и функции для операций над
вариантными массивами
Function VarArrayCreate
(const Bounds: array of Integer; VarType: Integer): Variant;
Создает вариантный массив из элементов типа VarType с количеством и границами измерений, указываемых параметром Bounds
Function VarArrayDimCount
(const A: Variant): Integers;
Возвращает количество измерений вариантного массива А или 0, если А не массив
Function VarArrayHighBound
(const A: Variant; Dim: Integer): Integer;
Возвращает верхнюю границу индекса вариантного массива А по измерению Dim
Function VarArrayLock
(var A: Variant): Pointer;
Блокирует массив (предотвращает его возможные изменения размеров) и возвращает указатель на связанные с ним данные
Function VarArrayLowBound
(const A: Variant; Dim: Integer): Integers;
Возвращает нижнюю границу индекса вариантного массива А по измерению Dim
Function VarArrayOf
(const Values: array of Variant): Variants;
Создает одномерный вариантный массив по перечню значений, содержащихся в открытом массиве Values. Нижняя граница индексов вариантного массива в этом случае равна 0
Изменяет верхнюю границу индекса вариантного массива А на величину HighBound. Вызов процедуры игнорируется, если массив был заблокирован функцией VarArrayLock
Function VarArrayRef(const A:
Variant): Variants;
Возвращает ссылку на вариантный массив. Используется при обращении к API-функциям