nextupprevious
 

Next:6.1.5 Вычисление единственного значения-функции
Up:6.1 Подпрограммы: процедуры и функции
Previous:6.1.3 Изменение действия-выходные параметры
 


6.1.4 Получение результатов -- выходные параметры

Действие, реализуемое процедурой, может при разных вызовах приводить к изменению значений разных переменных. Это достигается с помощью выходных параметров (или параметров-переменных). При вызове процедуры фактический параметр, соответствующий выходному формальному параметру, должен быть переменной (вспомним, например, фактические параметры стандартной процедуры $Read$). Спецификацию выходных формальных параметров определяет синтаксическая диаграмма рис. 6.4.

OutFPSection =  var ident { "," ident } ":" FormalType.

Рис. 6.4. Спецификация выходных формальных параметров

При вызове процедуры в фактических параметрах вычисляются все индексные выражения, если они есть, а полученные переменные связываются с соответствующими выходными формальными параметрами. Эта связь имеет место до тех пор, пока не завершится выполнение данного вызова, и любые действия с формальными параметрами-переменными, выполняемые в это время внутри процедуры, в действительности выполняются над соответствующими переменными, подставляемыми в качестве фактических параметров (в частности, если фактический параметр не содержит индексов, то он и есть та переменная, с которой связывается соответствующий формальный параметр). Например, в программе МаксТри, приведенной ниже, при первом вызове процедуры Зам обмениваются своими значениями переменные $X$ и $Y$, а при втором -- $Y$ и $Z$.

module МаксТри;
    (* Максимум из трех целых *)
    var X,Y,Z : integer;
    procedure Зам(var A : Integer; var B : Integer);
        var C : integer;
    begin C := A; A := B; B := C end Зам;
begin
    read(X,Y,Z);
    if$<$ Y then Зам(X,Y) end; (*$\{ X \geq Y \}$ *)
    if$<$ Z then Зам(X,Z) end; (*$\{ X \geq Y, X \geq Z \}$*)
    write(X)
end МаксТри.

Рассмотрим вызов Зам(K, M[K]),  в котором $K$ -- это целая переменная, а $M$ -- переменная типа array[1..100] of integer. Поскольку индексные выражения в фактических параметрах вычисляются до связывания параметров, справедливо свойство
 

$\{K=3, M[3]=5, M[5]=7\}$ Зам$(K,M[K]) \{K=5, M[3]=3, M[5]=7\}.$

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

type MATР = array 2 , 2 of integer;
procedure УМН (var X, Y, Z : MATР);
begin
Z[1,1] := X[1,1] $\ast$ Y[1,1] + X[1,2] $\ast$ Y[2,1];
Z[1,2] := X[1,1] $*$ Y[1,2] + X[1,2] $*$ Y[2,2];
Z[2,1] := X[2,1] $*$ Y[1,1] + X[2,2] $*$ Y[2,1];
Z[2,2] := X[2,1] $*$ Y[1,2] + X[2,2] $*$ Y[2,2];
end;

Пусть даны переменные $A,$$B$ и $C$ типа MATР и матрицы

$M_1=\pmatrix{1 & 1\cr 1 & 1},M_2=\pmatrix{2 & 2\cr 2 & 2},\noindent M_3=\pm......{4 & 4\cr 4 & 4}, M_4=\pmatrix{4 & 10\cr 4 & 10},M_5=\pmatrix{4 & 4\cr 6 & 6}$

Тогда справедливы следующие утверждения

$\{A = M_1, B = M_2 \}$ УМН$ (A,B,C) \{A = M_1, B = M_2, C = M_3\},$
$\{A = M_1, B = M_2 \}$ УМН$(A,B,A) \{A = M_4, B = M_2 \},$
$\{A = M_1, B = M_2 \}$ УМН$(A,B,B) \{A = M_1, B = M_5 \}.$

С другой стороны, если у процедуры УМН два первых параметра сделать параметрами значениями, т.е. изменить заголовок на

procedure УМН (X, Y: МАТР; var Z : MATР);

получаем следующие свойства:
$\{A = M_1, B = M_2 \}$ УМН(A,B,C) $\{A = M_1, B = M_2, C = M_3 \},$
$\{A = M_1, B = M_2 \}$ УМН(A,B,A) $\{ A = M_3, B = M_2 \},$
$\{A = M_1, B = M_2 \}$ УМН(A,B,B) $\{A = M_1, B = M_3 \}.$

Next:6.1.5 Вычисление единственного значения-функции
Up:6.1 Подпрограммы: процедуры и функции
Previous:6.1.3 Изменение действия-выходные параметры


© В.Н. Касьянов, Е.В.Касьянова, 2004