В версии 7.0 можно в качестве параметров-переменных использовать массивы и строки открытого типа, у которых не задаются размеры. В качестве фактического параметра в этом случае можно использовать массив или строку любого размера, однако массив должен состоять из тех же компонент, что и компоненты открытого массива. Такие параметры введены для того, чтобы подпрограмма могла обрабатывать массив или строку любого размера. Фактический размер массива в этом случае может быть определен с помощью функции High. Открытый массив задается как и обычный массив, но только без указания типа индекса. Следует иметь в виду, что индексация элементов открытого массива всегда начинается с нуля, а максимальный индекс элемента равен значению функции High.
Пример 2.14. Функция вычисления максимального элемента в массиве. И в качестве передаваемого параметра используется массив открытого типа:
Function Max(Var Mas: array of lnteger): lnteger;
Var Ма: Integer; i: Byte;
Begin Ма - Mas[0];
For i:= 1 to High(Mas) Do
If Ма < Mas[i] then Ма:= Mas[i];
Max: = Ма
End;
В этом примере в подпрограмму передается только один параметр и она может работать с любым одномерным массивом целых чисел. Однако следует иметь в виду, что при работе подпрограммы для открытого массива в стеке создается его копия и это может его переполнить и, следовательно, произойдет сбой. Заполнение стека снижает быстродействие.
Разновидность открытого массива - открытая строка, которая может задаваться либо с помощью стандартного типа OpenString, либо с помощью типа String и использования ключа компилятора $Р+. Например, заголовок процедуры, заполняющей каким-либо символом строку, может иметь вид:
Procedure FullChar(Var Str: OpenString; Ch: Char);
или
$Р+ Procedure FillChar(Var Str: String; Ch: Char);
Параметры-процедуры и параметры-функции
Передаваемым параметром может быть параметр-процедура или параметр-функция, т.е. параметр процедурного типа. Фактически этот параметр является параметром-значением, т.к. записывается без зарезервированного слова Var.
В качестве фактического параметра в этом случае используется соответствующая процедура или функция, имеющая необходимое количество параметров требуемых типов.
Для параметров-процедур и параметров-функций существуют те же правила, что и для других переменных процедурного типа: подпрограммы должны компилироваться с ключом $F+ или иметь директиву far, не должны быть стандартными подпрограммами, не должны объявляться внутри других подпрограмм, не должны иметь директив inline или interrupt.
Пример 2.15. Программа, печатающая таблицы сложения и умножения двух целых чисел в заданном диапазоне.
Program EXAMPLE_2_5;
Type Func = function(X,Y:lnteger): Integer;
{$F+}
Function Add(X, Y: Integer): Integer;
Begin Add:= X +Y End;
Function Multiply(X, Y: Integer): Integer; Begin Multiply: = X * Y End;
{$F-} {Процедура печати таблицы}
Procedure PrintTable(A, В: Integer; Operation: Func);
Var i, j: Integer;
Begin
For i:= 1 to A do
begin
For j: = 1 to В do
Write(0peration(i,j): 5);
end;
WriteLn
End;
BEGIN
PrintTable(10, 5, Add); Writeln;
PrintTable(10, 5, Multiply)
END.
Процедура EXIT
Известно, что оператор GOTO нельзя использовать для досрочного выхода из подпрограммы. В Турбо Паскале для этой цели используется процедура EXIT. Процедура EXIT завершает работу подпрограммы с возвратом в вызвавший его блок.
Пример 2.16. Функция, определяющая первое отрицательное число в массиве.
Function Minus(Var Massiv; N: Integer): Real; {Здесь Massiv - параметр без типа}
Begin Minus:= 0;
For i:= 1 to do
if T(Massiv)[i] < 0 Then {преобразование типа}
begin
Minus:= T(Massiv)[i];
EXIT {досрочный выход из функции}
end
End;
Ниже будет кратко рассмотрено использование в подпрограммах других директив.
Директивы подпрограмм
Турбо Паскаль имеет специальные средства управления транслятором при использовании подпрограмм - директивы. Директивы уточняют действие компилятора и распространяются на всю подпрограмму и только на нее. То есть, если за подпрограммой следует другая подпрограмма, стандартная директива, указанная за заголовком первой, не распространяется на вторую.
Директива EXTERNAL позволяет использовать в программе подпрограммы, написанные на языке Ассемблера и скомпилированные отдельно. Директива ASSEMBLER позволяет написать подпрограмму полностью на языке Ассемблера. При этом во время компиляции подпрограмма будет автоматически скомпилирована встроенным ассемблером пакета Турбо Паскаль. Директива INLINE позволяет включать в текст программы команды, записанные непосредственно в машинных кодах. Директива INTERRUPT предназначена для процедур, обрабатывающих прерывания.
Более подробно об использовании директив при работе с подпрограммами можно ознакомиться в рекомендуемой литературе [5, с.62; 4, п.8.2, п. 11.1-11.8].