按值调用
x
and y
in是用实参初始化p
的局部变量,while是全局变量,所以调用等价于:i
p( a[i],a[i] )
x := 1 /* The value of a[i] */
y := 1 /* The value of a[i] */
x := 2 /* x + 1 */
i := 2 /* i + 1 */
y := 2 /* y + 1 */
最后打印值 1、2,因为它们是 的值a[1]
,a[2]
没有改变。
通过引用调用
x
和y
in都是and (again)p
的别名(从调用过程开始),所以调用等价于:a[1]
a[1]
i = 1
a[1] := 2 /* a[1] + 1 */
i := 2 /* i + 1 */
a[1] := 3 /* a[1] + 1 */
最后打印值 3、2。
按名称呼叫
当简单变量作为参数传递时,按名称调用等同于按引用调用,但在传递表示内存位置的表达式(如下标)时则不同。在这种情况下,每次遇到实际参数时都会重新评估它。所以在这种情况下,这是调用的效果p( a[i],a[i] )
:
a[1] := 2 /* since i = 1, the result is equal to a[1] + 1 */
i := 2 /* i + 1 */
a[2] := 3 /* since i is now 2, the result is equal to a[2] + 1 */
最后打印值 2、3。在实践中,实现调用一个匿名函数(“thunk”),每次它必须评估一个参数。
按值调用结果
只是为了完成讨论,这里是值结果参数传递的情况,其中x
和y
在过程执行开始时使用实际参数的值进行初始化,并且在过程执行结束时,被复制回原来的变量地址:
x := 1 /* The value of a[i] */
y := 1 /* The value of a[i] */
x := 2 /* x + 1 */
i := 2 /* i + 1 */
y := 2 /* y + 1 */
a[1] := 2 /* the value of x is copied back to a[1] */
a[1] := 2 /* the value of y is copied back to a[1] (not a[2]!) */
最后打印值 2, 2。
有关传递参数的不同方式的讨论,请参见this。