Sru*_*mha 2 pascal pass-by-reference call-by-value
好吧,我和我的朋友就下面的代码进行了辩论。我们对它产生的输出有点困惑。有人可以澄清以下代码段的按引用调用和按值调用结果吗?
program params;
var i: integer;
a: array[1..2] of integer;
procedure p(x,y: integer);
begin
x := x + 1;
i := i + 1;
y := y + 1;
end;
begin
a[1] := 1;
a[2] := 2;
i := 1;
p( a[i],a[i] );
output( a[1],a[2] );
end.
Run Code Online (Sandbox Code Playgroud)
在参数通过 value-result 和通过引用传输到过程 p 的情况下,该程序的结果输出。
按价值调用
x和yinp是用实参初始化的局部变量,whilei是全局变量,所以调用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 */
Run Code Online (Sandbox Code Playgroud)
最后打印值 1, 2,因为它们是 的值a[1],a[2]未更改。
参考调用
双方x并y在p有别名a[1]和(再次)a[1](因为i = 1当程序被调用),所以调用等效于:
a[1] := 2 /* a[1] + 1 */
i := 2 /* i + 1 */
a[1] := 3 /* a[1] + 1 */
Run Code Online (Sandbox Code Playgroud)
最后打印值 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 */
Run Code Online (Sandbox Code Playgroud)
最后打印值 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]!) */
Run Code Online (Sandbox Code Playgroud)
最后打印值 2, 2。
有关传递参数的不同方式的讨论,请参见例如this。
| 归档时间: |
|
| 查看次数: |
3347 次 |
| 最近记录: |