【问题标题】:Call by reference, value, and name按引用、值和名称调用
【发布时间】:2013-04-05 00:15:24
【问题描述】:

我试图理解按引用、值和名称调用之间的概念差异。

所以我有以下伪代码:

foo(a, b, c)
{
   b =b++;
   a = a++;
   c = a + b*10
}

X=1;
Y=2;
Z=3;
foo(X, Y+2, Z);

如果 a、b 和 c 都是通过引用调用,则 foo 调用之后的 X、Y 和 Z 是什么? 如果 a、b 和 c 是按值/结果调用? 如果 a、b 和 c 是按名称调用的?

另一个场景:

X=1;
Y=2;
Z=3;
foo(X, Y+2, X);

我正在努力为即将到来的期末考试抢占先机,这似乎是一个很好的复习问题。 Pass-by-name 对我来说绝对是最陌生的。

【问题讨论】:

标签: pass-by-reference pass-by-value pass-by-name


【解决方案1】:

当您按值传递参数时,它只是复制函数参数中的值,并且在函数中对该变量所做的任何事情都不会反映原始变量,例如

foo(a, b, c)
{
   b =b++;
   a = a++;
   c = a + b*10
}

X=1;
Y=2;
Z=3;
foo(X, Y+2, Z);
//printing will print the unchanged values because variables were sent by value so any //changes made to the variables in foo doesn't affect the original.
print X; //prints 1
print Y; //prints 2
print Z; //prints 3

但是当我们通过引用发送参数时,它会复制变量的地址,这意味着我们对函数中的变量所做的任何事情,实际上都是在原始内存位置完成的,例如

foo(a, b, c)
{
   b =b++;
   a = a++;
   c = a + b*10
}

X=1;
Y=2;
Z=3;
foo(X, Y+2, Z);

print X; //prints 2
print Y; //prints 5
print Z; //prints 52

按名称传递; Pass-by-name

【讨论】:

  • 对于传递引用,传递的东西必须是左值(即可赋值)。 Y+2 不是左值,所以我不确定分配给它意味着什么。
  • 我在您的按值调用和按引用调用的示例中找不到任何区别......您只是在评论中更改变量的值。我想知道如何通过值和引用不同地传递变量,因为您的示例中的所有代码都是相同的。所以,我无法得到它。
【解决方案2】:

按值调用:正常方式...将实际参数的值复制到形式参数。

引用调用:传递地址而不是参数,形式参数指向实际参数。

按名称调用:与宏一样,整个函数定义代替了函数调用,形参只是实参的别称。

【讨论】:

    【解决方案3】:

    按价值 - 功能没有变化。函数完成后,您的所有操作都会消失。

    通过参考 - 你的行为确实改变了变量。 按名称 - 我从未听说过......

    传递 x+1 不会改变,只是告诉函数 3 而不是 2 或等等...

    【讨论】:

      【解决方案4】:

      如果是按值传递,这不会改变 X、Y 或 Z 的值。当您使用诸如“foo()”之类的函数时,它基本上将变量(x、y 和 z)复制到其他变量(a、b 和 c)中并对其执行某些操作,而不更改原始变量(x、 y 和 z)。要更改一个值,您必须返回一个值,如下所示:

      foo(a, b, c)
      {
      a = a++;
      b = b++;
      c = a + b * 10;
      return c;
      }
      
      x = 1;
      y = 2;
      z = 3;
      z = foo(x, y+2)
      

      那么 x 和 y 将相同,但 z 将是 (x+1)+(y+1)*10,在本例中为 32。

      【讨论】:

        【解决方案5】:

        在javascript中:

        1. 像字符串、数字这样的原始类型变量总是作为传递传递 按价值计算。
        2. 数组和对象根据这些条件以引用传递或值传递的方式传递。

          • 如果你用新的对象或数组改变那个对象或数组的值,那么它是按值传递的。

            object1 = {item: "car"}; array1=[1,2,3];

          在这里您正在分配新对象或数组。您没有更改属性的值 旧对象。所以它是按值传递的。

          • 如果您要更改对象或数组的属性值,则它是通过引用传递的。

            object1.item= "car"; array1[0]=9;

          在这里您正在更改旧对象的属性值。您没有将新对象或数组分配给旧对象。因此它是通过引用传递的。

        代码

            function passVar(object1, object2, number1) {
        
                object1.key1= "laptop";
                object2 = {
                    key2: "computer"
                };
                number1 = number1 + 1;
            }
        
            var object1 = {
                key1: "car"
            };
            var object2 = {
                key2: "bike"
            };
            var number1 = 10;
        
            passVar(object1, object2, number1);
            console.log(object1.key1);
            console.log(object2.key2);
            console.log(number1);
        
        Output: -
            laptop
            bike
            10
        

        【讨论】:

          【解决方案6】:

          按值调用中,传递变量的副本,而在按引用调用中,传递变量本身。在按值调用中,实际参数和形式参数将在不同的内存位置创建,而在按引用调用中,实际参数和形式参数将在同一内存位置创建。

          【讨论】:

            猜你喜欢
            • 2013-12-15
            • 2012-09-28
            • 2015-06-07
            • 2017-02-07
            • 2013-10-02
            • 2019-10-19
            • 1970-01-01
            • 2020-11-15
            • 2020-08-19
            相关资源
            最近更新 更多