按值调用
p中的x和y是带实参的局部变量初始化,而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] 的值,它们没有改变。
引用调用
p 中的 x 和 y 都是 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 在过程执行开始时使用实际参数的值进行初始化,并且,在程序执行结束,都复制回original变量addresses:
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。