Иллюстрированный самоучитель по Турбо Паскалю
Нетипизированные параметры - переменные
Еще одно очень полезное нововведение фирмы 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 индексная арифметика. Еще раз напомню, что
в случае многомерных массивов их элементы располагаются в памяти так, что при
переходе от младших адресов к старшим наиболее быстро меняется самый правый
индекс массива.