参数传递有传名(call by name),传值(call by value),传地址(call by reference), 传结果(call by result)等方式,试述编译程序在处理“传值”“传地址”方式时的要点,并指明处理“传名”与“传地址”,以及“传值”与“传结果”方式之间的主要差别。
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
传地址: 所谓传地址就是把实参的地址传递给相应的形参。在过程中每个形参对应一个单元,称为形式单元。形式单元用来存放相应的实参地址。当调用一个过程时,调用段必须预先把实参的地址传递到一个被调用段可以得到的地方。如果实参是一个变量(包括下标变量),则直接传递它的地址。如果实参试常数或者其它表达式(如A+B)就先计算它的值并存放在某一临时单元中。然后传递这个临时单元的地址,当程序转入被调用段之后,被调用段首先把实参地址抄进自己相应的形式单元中,过程体对形参的任何赋值都被处理成对形式单元的间接访问(即对形势单元中存储的实参地址对实参进行访问)。这样,当被调用段的工作完毕进行返回时,实参单元已经持有所期望的值。
传值:传值是一种最简单的参数传递方法。调用段把实参的值计算出来并存放在被调用段可以获得的地方。被调用段开始工作时,将这个值拷贝到自己相应的形式单元中,就像使用局部名一样使用这些形式单元,即形参是如同一种先从实参获得初值的局部变量,获得初值后就没有联系了。这点与传地址不同。
传结果:和传地址相思但不等价的另一种传值方式是传结果。这种方法的实质是形参具有两个单元。第一个单元存放的实参的地址。第二个单元存放的实参的值,在过程中对形参的任何引用和赋值看成是对它的第二个单元的直接访问。但是在调用返回之前必须把第二个单元的值存放到第一个单元指示的地址中。
传名:传名是ALGOL语言定义的一种特殊形式的形参结合方式。使用替换规则解释传名的参数的意义。过程调用的作用相当于把被调用的过程体抄到调用出现的地方,但把其中任何一个出现的形参都替换成相应的实参(文字替换)。如果在替换过程中出现了和局部变量相同的标志符,则使用不同的标识替换。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
procedure P(X,Y,Z)
begin:
Y:=Y+1;
Z:=Z+X;
end P;
begin:
A:=2;
B:=3;
p(A+B,A,A);
Print A;
end
求程序的输出
传名:由于过程调用时被调用过程和形参均采用文字替换的形式,所以调用后的程序如下:
A:=2
B:=3
A:=A+1
A:=A+A+B
A = 3+3+3= 9
传地址:使用T代表A+B,再使用动态分析
T = A+B = 2+3 =5(X)
A = 2 = 3(Y)= 8(Z)
传结果:使用T代表A+B,再使用动态分析
X: T的地址 5
Y:A的地址 2 Y=Y+1 A的地址 3
Z:A的地址 2 Z=Z+X A的地址 7
执行结束后先将Y的值返回,A =3 ,但是随后将 Z的地址返回,A=7
传值:A =2 因为和A没啥关系