我已经学习Java几个月了,现在我开始学习C.
我有点困惑,我的印象是通过引用传递一个对象并传递指向该对象的指针是同样的事情:我认为不同的是,在Java中所有对象的传递都是自动完成的指针,如C必须在这里和那里洒上小小的星号和&符号.最近,在谈话中,我确信存在差异!
传递引用和传递指针有什么区别?
Java 和 C 都没有传递引用.它们都是严格按价值传递的.
传递引用语义意味着当您更改方法中参数的值时,调用者将在参数中看到该更改.
现在,您可能会想:"但在Java中就是这种情况!如果我在方法期间更改对象,则调用者会看到该更改." 该对象不是参数.参数只是变量 - 如果更改该变量的值,调用者将看不到.例如:
public void foo(Object x) { x = null; } public void caller() { Object y = new Object(); foo(y); // y is still not null! }
如果参数真的通过引用传递,则y
之后将为null.相反,值y
只是一个引用,该引用按值传递.令人困惑的是因为"参考"这个词在两个方面都有,但它们是不同的东西.
您可能希望查看我关于C#参数传递的文章,看看如果Java 确实具有传递引用语义,那么C#会在您使用ref
关键字的时候(并且仅在何时)执行.
您可能还想查看与该主题相关的Stack Overflow答案的注释.
我认为不同之处在于,在Java中,所有对象的传递都是自动完成的,而在C中,必须实际上在这里和那里撒上小星号和符号.
概念,这是非常正确的.如果我们是迂腐的(这是一件好事),我们甚至可以说Java中根本没有传递对象.传递的只是"指针",在Java中称为引用.所有间接都是自动完成的.因此,当您在C中执行"objref-> foo"而不是"objref.foo"并且因为使用指针而无法使用点时,在Java中您仍然可以使用点,因为它不知道任何其他内容无论如何访问成员.在C语言中,你可以通过指针(在这里,它是实际上是所谓的指针),并可以通过在这种情况下副本传递对象本身.在C中,您可以使用星号或" - >"通过间接访问指针引用的对象.在Java中
如果我们再次迂腐(现在再次变得更加重要),那么在Java和C中都没有"通过引用传递".我们在Java中传递的是指向对象的引用/指针,在C中我们传递对象的副本(显然是大小写)或者我们再次传递指向对象的指针的副本.所以在两种情况下 - Java和C - 我们传递的是对象的地址.不是说基本Java类型,它们将被复制在Java和C -即使你可以在C通过他们的地址也是如此,没有一个聚合类型(即结构),并用C在"原始类型"没有任何区别在于看待.