Если перед именем формального параметра стоит ключевое слово var, то такой параметр есть параметр-переменная. Примерами таких параметров служат x1 и x2 в заголовке
procedure sq(a, b, c: real; var x1, x2: real);
Фактический параметр, соответствующий параметру-переменной, может быть только переменной (не константой и не выражением).
При вызове процедур (функций) параметры-переменные обрабатываются так: для формального параметра используется именно та ячейка, которая содержит соответствующий фактический параметр.
Пример. При вызове процедуры sq оператором sq(p, q, r, y, z) для переменныхx1 и x2 используются непосредственно те ячейки, которые отведены для y и z. Поэтому оператор присваивания x1 := (-b + sqrt(d)) / (2 * a) засылает полученное значение в y.
Под формальные и фактические параметры-значения транслятор отводит разные области памяти. Поэтому результат выполнения процедуры может быть передан только через параметр-переменную.
var a, b: integer; procedure h(x: integer; var y: integer); begin x := x + 1; y := y + 1; writeln(x, y) end; begin a := 0; b := 0; h(a, b); writeln(a, b); readln end.
Результаты, выдаваемые процедурой h – 11; основная ветка программы выводит 01.
Разберем этот пример: фактический параметр a соответствует формальному параметру-значению x, а фактический параметр b – формальному параметру-переменной y. Под параметры a и x отведены две разные ячейки памяти, а под b и y– одна и та же ячейка.
При обращении к h(a, b) из ячейки a пересылается значение 0 в ячейку x, а в ячейку y засылается адрес ячейки b, содержащей 0, т.к. в процедуре h параметр x – это параметр-значение, а y – параметр-переменная.
При выполнении оператора x := x + 1 в ячейку x прибавляется 1 и в ячейке xокажется 1, а в ячейке a по-прежнему 0.
Выполнение оператора y := y + 1 имеет следующий смысл: «взять число из ячейки, адрес которой находится в y (т.е. из ячейки b), прибавить 1 и заслать в ту же ячейку (т.е. в b)».
Поэтому в результате выполнения оператора y := y + 1 значение ячейки bстанет 1. Оператор печати из процедуры выдаст содержимое ячейки x и ячейки y, т.е. 1 и 1. Оператор печати в программе напечатает содержимое a, которое осталось равным 0, и содержимое ячейки b, которое теперь равно 1.
Процедуры в Паскале допускают рекурсию, т.е. процедура может вызвать сама себя.
Если в процедуре p есть обращение к процедуре q, описанной ниже, то перед описанием p процедура q декларируется как forward: после заголовка процедуры qставится двоеточие, а затем ключевое слово forward. В этом случае параметры процедуры описываются только в операторе с forward. В заголовке самой процедуры параметры опускаются.
Пример.
procedure q(x: t1): forward; procedure p(x: y); begin q(a) end; procedure q; begin p(b) end;