|
Нетипизированные параметры - переменные
Еще одно очень полезное
нововведение фирмы Borland - возможность использования
нетипизированных параметров. Параметр считается нетипизированным,
если тип формального параметра-переменной в заголовке
подпрограммы не указан, при этом соответствующий ему
фактический параметр может быть переменной любого типа.
Заметим, что нетипизированными могут быть только параметры-переменные.
Нетипизированные параметры обычно используются
в случае, когда тип данных несущественен. Такие ситуации
чаще всего возникают при разного рода копированиях одной
области памяти в другую, например, с помощью процедур
BLOCKREAD, BLOCKWRITE, MOVE и т.п.
Нетипизированные параметры в сочетании
с механизмом совмещения данных в памяти (см. п.4.4)
можно использовать для передачи подпрограмме одномерных
массивов переменной длины (этот способ можно использовать
в Турбо Паскале версии 6.0 и более ранней, в которых
нет открытых массивов).
В примере 8.4 функция NORMA вычисляет
норму вектора, длина которого меняется случайным образом.
Стандартная константа MAXINT содержит максимальное значение
целого типа INTEGER и равна 32767.
Следует учесть, что при обращении к
функции NORMA массив X помещается в стек и передается
по ссылке, поэтому описание локальной переменной А в
виде одномерного массива максимально возможной длины
в 65532 байта (встроенная константа MAXINT определяет
максимально возможное значение типа INTEGER и равна
32767), совпадающего с X, на самом деле не приведет
к выделению дополнительного объема памяти под размещение
этой переменной. Иными словами, переменная А - фиктивная
переменная, размер которой никак не влияет на объем
используемой памяти. С таким же успехом можно было бы
объявить ее в виде массива из одного элемента, правда,
в этом случае необходимо позаботиться
об отключении контроля выхода индекса за границы
диапазона.
Пример 8.4
const
NN = 100; {Максимальная длина вектора}
var
а : array [1..NN] of Real;
i, j, N : Integer;
{----------------}
Function Norma (var x; N: Integer) :
Real;
var
a : array [1..2*MaxInt div SizeOf (Real)
] of Real absolute x;
i : Integer;
s : Real;
begin {Norma}
s := 0;
for i := 1 to N do
s := s + sqr (a [i] ) ;
Norma := sqrt(s)
end {Norma} ;
{-------------------}
begin {main}
for i := 1 to 10 do
begin
N := Random (NN) + 1; {Текущая длина
вектора}
for j := 1 to N do
a [ j ] : = Random ;
WriteLn ('N = ', N:2,норма=',Norma(a,
N):10:7)
end
end {main} .
Как видно из рассмотренного примера,
передача одномерных массивов переменной длины не вызывает
никаких трудностей. Сложнее обстоит дело с многомерными
массивами, однако и в этом случае использование описанного
приема (нетипизированный параметр и совмещение его в
памяти с фиктивной переменной) все-таки проще, чем описанная
в гл. 6 индексная арифметика. Еще раз напомню, что в
случае многомерных массивов их элементы располагаются
в памяти так, что при переходе от младших адресов к
старшим наиболее быстро меняется самый правый индекс
массива.
|