在我们使用pass by reference的C ++中,我们引用从参数传递给函数参数的地址,该函数的参数本质上是一个指针对吗?因此虽然它们本质上是同一个东西,别名和所有,但指针也不需要内存空间吗?因此,无论我们在参数函数中有什么,让我们调用B指向传递的参数的内存位置让我们调用A,而A又是我们值的内存位置(因为A传递了我们值的内存位置)作为论点)?
在我们使用pass by value的java中,我们复制了我们传递的任何地址(例如对象的引用)。
所以最后我并没有真正看到传递值和传递参考之间的区别。 pass by value为原始传递的参数在内存中分配空间,并且指向值并通过引用传递的副本将我们的值的内存位置作为参数(在内存中分配空间的指针)的参数传递给我们function用于指向值。
答案 0 :(得分:4)
在我们使用pass by reference的C ++中,我们引用了我们传递的任何地址 从参数到函数的参数,它本质上是一个指针对吗?
没有。引用是现有变量的别名(即替代名称) 但是在汇编级别,您的实现可能会将引用变量的地址放在要使用的被调用函数的地址寄存器(或类似的东西)中(如果这就是您的意思)。
但是为了简化,您可以将其视为一个自动取消引用的指针(这是我第一次启动时所做的)。但是当你进入语言时,引用实际上与指针基本不同。
所以虽然它们基本上是同一个东西,别名和所有,但指针也不需要内存空间吗?
C ++级别的指针需要空间(因为它是可寻址的)。您可以获取指针的地址。从根本上说,参考不需要空间(因为你不能拿它的地址)。在实现级别,它可能有也可能没有物理内存位置,具体取决于编译器如何实现它。
因此,无论我们在参数函数中拥有什么,让我们调用B指向传递参数的内存位置让我们调用A
如果你用代码示例解释了上面的内容,那就太好了。但我想我明白了。假设函数没有内联,那么作为引用传递的任何参数都需要某种形式的链接回原始对象(因为引用总是从根本上引用活动对象)。那怎么办呢。编译器实现细节(所以你不应该在乎)。但可能是堆栈上的指针,或者可能只是地址寄存器中的地址。
反过来又是我们值的内存位置(因为A传递了我们值的内存位置作为参数)?
不管怎样。引用在语言级别没有物理位置。所以编译器可以用这个很好的小技巧。
在我们使用pass by value的java中,我们复制了我们传递的任何地址(例如对象的引用)。
在Java中,您可以按值传递引用。但Java引用基本上只是内存位置的指针。所以你按值传递指针。这是一种使用的技术。幸运的是,C ++并不限制您使用单一技术。
您可以按值或引用传递参数。您甚至可以通过值或引用将指针传递给对象。所以根据具体情况使用几种有趣的技术。
所以最后我并没有真正看到传递值和传递参考之间的区别。
也许这是因为你正在考虑java引用(通过值传递)。
在C ++中。如果按值传递,则表示您正在创建一个作为参数传递的新对象(这意味着您可以复制原始文件,这可能会花费成本)。如果通过引用传递,则将别名传递给对象。因此,当您与正在修改原始对象的对象进行交互时。
int inc(int val) // pass by value
{
return ++val; // increment the passed value and return as a result.
}
int incref(int& val) // pass by reference
{
return ++val; // increment the reference.
// Since the reference is an alias this increment affects the
// original object. The result is returned.
}
void code()
{
int x = 5;
int y = inc(x); // x =5 and y = 6
int a = 8;
int b = incref(a); // a = 9 and b = 9
}
传递值在内存中为原始传递的参数分配空间,并且指向值并通过引用传递的副本将值的内存位置作为参数(在内存中分配空间的指针)的参数传递)在我们的函数中用来指向值。
抱歉,我输了。
答案 1 :(得分:1)
Honest-to-god pass-by-value创建变量值的副本并将其传递给函数。这通常通过将值直接推送到堆栈来完成。被调用的函数无法修改原始值。
示例:
a = 5
double(a); <-- but this is pass-by-value
print a
end
function double(x) <-- x is a variable with a value of 5
x = 2*x;
print x;
return x;
在上面的示例中,值5传递给double()。函数中的x
变为10,并打印10。该函数返回,并打印 5 。由于a
的值(不是其地址)被传递给double(),因此double()无法更改a
的值。
如果我们传递了一个指向a
(通过引用传递)的指针,那么更改a
的值就没有问题。
答案 2 :(得分:0)
在传递值中,计算地址中的值并在运行时传递。但是在通过引用传递时,没有确定值只有一个地址被传递给您自己读取值的函数并直接在内存位置进行更改 - 而不是传递给您的值,如传递值 - 这是非常的低级别并且可能导致问题,因为如果一个或多个程序同时对内存位置执行操作,则可能存在歧义。这是java不支持指针的原因之一。
在传递值时,在您的功能执行操作时,内存位置中的数据不会更改。因为它正在对它的副本执行操作。有点像java中的多线程。