14.4.6 Массив констант |
Вверх Предыдущий Следующий |
Free Pascal в режиме Object Pascal или Delphi, поддерживает конструкцию Array of Const (массив констант) для передачи параметров в подпрограмму. Это частный случай конструкции Open array (открытого массива), так он может передать любое выражение в функцию (или процедуру). Тип результата выражения должен быть простым: структура не может быть переданы как аргумент. Это означает, что могут быть переданы порядковые и вещественные типы, строки, а также указатели на классы и интерфейсы. Элементы array of const преобразуются в специальную вариантную запись: Type PVarRec = ^TVarRec; TVarRec = record case VType : Ptrint of vtInteger : (VInteger: Longint); vtBoolean : (VBoolean: Boolean); vtChar : (VChar: Char); vtWideChar : (VWideChar: WideChar); vtExtended : (VExtended: PExtended); vtString : (VString: PShortString); vtPointer : (VPointer: Pointer); vtPChar : (VPChar: PChar); vtObject : (VObject: TObject); vtClass : (VClass: TClass); vtPWideChar : (VPWideChar: PWideChar); vtAnsiString : (VAnsiString: Pointer); vtCurrency : (VCurrency: PCurrency); vtVariant : (VVariant: PVariant); vtInterface : (VInterface: Pointer); vtWideString : (VWideString: Pointer); vtInt64 : (VInt64: PInt64); vtQWord : (VQWord: PQWord); end; Внутри тела процедуры аргумент array of const эквивалентен открытому массиву TVarRec: Procedure Testit (Args: Array of const); Var I : longint; begin If High(Args)<0 then begin Writeln ('Нет аргументов'); exit; end; Writeln ('Got ',High(Args)+1,' arguments :'); For i:=0 to High(Args) do begin write ('Аргумент ',i,' имеет тип '); case Args[i].vtype of vtinteger : Writeln ('Целое, Со значением :',args[i].vinteger); vtboolean : Writeln ('Boolean, Со значением :',args[i].vboolean); vtchar : Writeln ('Символ, Со значением : ',args[i].vchar); vtextended : Writeln ('Вещественное, Со значением : ',args[i].VExtended^); vtString : Writeln ('ShortString, Со значением :',args[i].VString^); vtPointer : Writeln ('Указатель,, Со значением : ',Longint(Args[i].VPointer)); vtPChar : Writeln ('PChar,, Со значением : ',Args[i].VPChar); vtObject : Writeln ('Объект, С именем : ',Args[i].VObject.Classname); vtClass : Writeln ('Ссылка на класс, С именем :',Args[i].VClass.Classname); vtAnsiString : Writeln ('AnsiString, Со значением :',AnsiString(Args[I].VAnsiString); else Writeln ('(Неизвестное) : ',args[i].vtype); end; end; end; В код этой процедуры можно передать произвольный массив элементов: S:='AnsiString 1'; T:='AnsiString 2'; Testit ([]); Testit ([1,2]); Testit (['A','B']); Testit ([TRUE,FALSE,TRUE]); Testit (['String','Иная строка']); Testit ([S,T]) ; Testit ([P1,P2]); Testit ([@testit,Nil]); Testit ([ObjA,ObjB]); Testit ([1.234,1.234]); TestIt ([AClass]); Если процедура объявлена с модификатором cdecl, то компилятор будет передать массив как откомпилированный под С. Он, эмулирует C конструкцию с переменным числом аргументов, как показано в следующем примере: program testaocc; {$mode objfpc}
Const P : PChar = 'пример'; Fmt : PChar = 'Этот %s показывает использование printf для вывода чисел (%d) и строк'#10; // Объявление стандартной функции printf:
procedure printf (fm : pchar; args : array of const);cdecl; external 'c'; begin printf(Fmt,[P,123]); end. Заметим, что это не верно для Delphi, поэтому код опирающйся на эту функцию не будет переносим.
|