PascalABC.NET

Параметры процедур и функций

Параметры, указываемые при описании подпрограммы, называются формальными. Параметры, указываемые при вызове подпрограммы, называются фактическими.

Если формальный параметр описан с предваряющим ключевым словом var или const, то его называют параметром-переменной и говорят, что он передается по ссылке. Если же параметр описан без слов var или const, то его называют параметром-значением и говорят, что он передается по значению. Слово ссылка используется в PascalABC.NET также в другом значении - для ссылочных типов.

Если параметр передается по значению, то при вызове подпрограммы значения фактических параметров присваиваются соответствующим формальным параметрам. Типы фактических параметров-значений должны быть совместимы по присваиванию с типами соответствующих формальных параметров.

Например, пусть имеется следующее описание процедуры:

procedure PrintSquare(i: integer);
begin
  writeln(i*i);
end;
Тогда при вызове PrintSquare(5*a-b) значение 5*a-b будет вычислено и присвоено переменной i, после чего выполнится тело процедуры.

Если параметр передается по ссылке, то при вызове подпрограммы фактический параметр заменяет собой в теле процедуры соответствующий ему формальный параметр. В итоге любые изменения формального параметра-переменной внутри процедуры приводят к соответствующим изменениям фактического параметра. Фактические параметры-переменные должны быть переменными, а их типы должны быть эквивалентны типам соответствующих формальных параметров.

Например, если описана процедура

procedure Mult2(var a: integer);
begin
  a := a*2;
end;
то после вызова Mult2(d) значение d увеличится в 2 раза.

В качестве фактического параметра-значения можно указывать любое выражение, тип которого совпадает с типом формального параметра или неявно к нему приводится.  В качестве фактического параметра-переменной можно указывать только переменную, тип которой в точности совпадает с типом формального параметра. 

При передаче параметра по ссылке в подпрограмму передается адрес фактического параметра. Поэтому если параметр занимает много памяти (массив, запись, строка), то обычно он также передается по ссылке. В результате в процедуру передается не сам параметр, а его адрес, что экономит память и время работы. При этом если параметр меняется внутри подпрограммы, то он передается с ключевым словом var, если не меняется - с ключевым словом const:

Например:

type
  Person = record
    name: string;
    age,height,weight: integer;
  end;

procedure Print(const p: Person);
begin
  write(p.name,' ',p.age,' ',p.height,' ',p.weight);
end;

procedure IncAge(var p: Person);
begin
  Inc(p.age);
end;

Отметим особенности передачи динамических массивов в качестве параметров подпрограмм.

Поскольку динамический массив является ссылкой, то при изменении формального параметра-динамического массива внутри подпрограммы меняется соответствующий фактический параметр. Например, в результате работы программы

procedure p(a: array of integer);
begin
  a[1] := 2;
end;

var b: array of integer := (1,1);

begin
  p(b);
  writeln(b[1]);
end.

будет выведено 2. Передавать динамические массивы по ссылке имеет смысл только в случае если память под динамический массив перераспределяется внутри подпрограммы:

procedure q(var a: array of integer);
begin
  SetLength(a,10);
end;