4.17.4. Функции
а) могут возвращать значения определенных пользователем типов, включая сложные;
б) внутри каждой функции предопределена доступная по чтению и записи локальная переменная Result, имеющая тот же тип, что и функция. Ее значение до первого присваивания не определено. После завершения процедуры-функции эта функция возвращает значение, присвоенное переменной Result. Использование переменной Result является более наглядным и современным, чем обычный синтаксис языка PASCAL для функций, где значение возвращается через доступную только по записи локальную переменную с именем, совпадающим с именем функции.
4.17.5. Оператор CASE.
Значения вариантов (в том числе диапазоны) не могут пересекаться. Расположение вариантов в порядке возрастания позволяет компилятору оптимизировать код.
4.17.6. Открытые массивы.
Открытым массивом называется массив, используемый как формальный параметр процедуры, длина которого задается не в месте задания процедуры, а при ее вызове. При этом при ее вызове могут использоваться массивы разной длины.
Замечание: если нужен массив переменной длины, для этих целей используют список (мы уже знаем, как это делать). Правда, работа с массивом требует меньше памяти и идет быстрее, чем со списком. В Delphi начиная с версии 2.0 одномерные открытые массивы можно использовать без описания соответствующего типа. С версии 4.0 поддерживаются двумерные открытые массивы. Имеются предопределенные функции Low и High, в качестве параметра которых подставляется имя массива. При этом Low возвращает номер первого элемента, а High — последнего. Надо отметить, что в Delphi (как и в С++, JavaScript и Java) все номера начинаются с 0, а не с 1.
Пример:
program ArcDemo; {MyData - открытый массив}
function Mean(MyData:array of Real):Real;
var i:Integer;
begin
Result:=0;
for i:=Low(MyData)to High(MyData)do {цикл от первого до
последнего элемента}
Result:=Result+MyData[i];
Result:=Result/(High(MyData)-Low(MyData)+1);
end;
var X:Real;
begin
X:=mean([1,9,9,7]); {задаем массив путем перечисления элементов}
end.
Имеется возможность передавать в процедуру открытый массив разнотипных переменных. Такой параметр должен быть описан как array of const. Он может передаваться как по имени (т.е. по указателю на массив), так и по значению (т.е. делается его копия). Внутри процедуры элементы массива рассматриваются как записи типа TVarRec, описанные в модуле System, причем имеется поле типа VType, позволяющее идентифицировать тип фактического параметра.
Пример функции, возвращающей строковое значение переменного числа параметров, а заодно и демонстрирующей не слишком последовательную методику преобразования выражений разных типов в строку:
function AllToStr(const MyParameters:array of const):string;
const
BString:array[Boolean] of string=('False','True');
var
i:Integer;
S:String;
begin
Result:='';
for i:=Low(MyParameters)to High(MyParameters)do
with TVarRec(MyParameters[i])do
begin
case VType of
vtInteger: s:=IntToStr(VInteger);
vtBoolean: s:=Bstring(Vboolean);
vtChar: s:=VChar;
vtEXtended: s:=FloatToStr(VExtended^);
vtString: s:=vString^;
vtPointer: s:=IntToHex(Longint(VPointer),8);
vtPChar: s:=StrPas(VPChar);
vtObject: s:=vObject.ClassName;
vtClass: s:=vClass.ClassName;
end{/case};
Result:=Result+s;
end; {/with...do}
end{/AllToStr};
При вызове
AllToStr([1,'+2','=3,',1e6,'>',1.5e-10,'is',1e6>1.5e-10,'.'])
возвратит строковое значение
1+2=3,1E6>1.5E-10 is true.
4.17.7. Переменные типа variant.
Иногда удобно писать процедуры общего назначения, которые должны выглядеть одинаково для параметров с переменными разного типа. В этом случае целесообразно вместо нескольких процедур использовать одну с параметрами типа variant.
Для переменных типа variant действуют особые правила присваивания: переменной
aMyVar:Variant;
можно присваивать выражения любых типов независимо от текущего значения переменной:
begin
...
aMyVar:=1;
...
aMyVar:=true;
...
aMyVar:='SomeString';
...
end;
При присваивании строковой переменной (или участии в строковом выражении) переменная вариантного типа возвращает строку с соответствующим значением. В предыдущем примере это было бы '1','true' и 'SomeString', соответственно.
Приведение типов для других случаев описывать не будем. Информацию по этому вопросу можно найти в специальной документации среды Delphi.
Работа с переменными типа variant гораздо медленнее чем для обычных, т.к. проверки и приведения типов во время исполнения программы занимают много времени. Кроме того, жесткость диагностики для этого случая значительно снижена, что может привести к возникновению не отслеживаемых компилятором ошибок. Поэтому, по мере возможностей, лучше избегать применения переменных variant. Их целесообразно использовать только в случае вызова DLL (Dynamic Link Libraries), написанных на языке С, для обеспечения совместимости по типу с параметрами функции из этих библиотек.