Question

I have been studying Java for a few months and am now starting to learn C.

I am a little confused, I was under the impression that passing an object by reference and passing a pointer to that object were the same thing: I thought the difference was that in Java all passing of objects is done with pointers automatically, where as in C one has to actually sprinkle little asterisks and ampersands here and there. Recently, in conversation, I was assured that there was a difference!

What is the difference between passing by reference and passing a pointer?

Was it helpful?

Solution

Neither Java nor C has pass-by-reference. They are both strictly pass-by-value.

Pass-by-reference semantics mean that when you change the value of the parameter in the method, the caller will see that change in the argument.

Now, you may be thinking: "But that's the case in Java! If I change an object during the method, the caller sees that change." The object isn't the parameter. The parameter is just the variable - and if you change the value of that variable, the caller won't see that. For example:

public void foo(Object x)
{
    x = null;
}

public void caller()
{
    Object y = new Object();
    foo(y);
    // y is still not null!
}

If the parameter were really passed by reference, y would be null afterwards. Instead, the value of y is just a reference, and that reference is passed by value. It's confusing because the word "reference" is in both terms, but they're different things.

You may want to look at my article about C# parameter passing to see what would be possible if Java did have pass-by-reference semantics, as C# does when (and only when) you use the ref keyword.

You may also want to look at the comments to my Stack Overflow answer related to the topic.

OTHER TIPS

I thought the difference was that in Java all passing of objects is done with pointers automatically, where as in C one has to actually sprinkle little asterisks and ampersands here and there.

Conceptional, that's quite right. If we are pedantic (and that's a good thing), we can even say objects are not passed at all in Java. What is passed is only ever the "pointer", which in Java is called the reference. All indirection is done automatically. So when you do "objref->foo" instead of "objref.foo" in C and can't use the dot because you work with a pointer, in Java you can still use the dot because it doesn't know anything else to access members anyway. In C, you can pass the pointer (and here, it is actually called pointer) and you can pass the object itself, in which case a copy is passed. In C, you access the object that a pointer refers to by indirection using the star or "->". In Java, the only way objects are accessed anyway are using the dot (objref.member).

If we are pedantic again (now more important again), neither in Java nor in C there is "pass by reference". What we pass in Java is the reference/pointer to the object and in C we either pass a copy of the object (obvious case) or we pass again just a copy of a pointer to the object. So in both cases - Java and C - what we pass are the addresses of the objects. Not talking about primitive java types, which are copied in both Java and C - even though you can pass their address in C too, there is no difference between an aggregate type (i.e a struct) and a "primitive type" in C in that regard.

The differences are subtle. At an assembly level, in both cases the address of the object is passed to the function. However, in the pointer case the parameter is an independent pointer which can be used to modify the target object (*pch = 'x') or can be used to access a different object (pch = "newstr"). In the reference case, the parameter is automatically indirected to the target object.

I believe a pointer is a variable that contains a reference. With & you can obtain a memory direction ( reference ), and with * you can access to the content of a memory direction. I suggest the book The C programming Language .

Regards

True pass-by-reference means that you can assign a new value to the reference, and this new value will be visible in the calling context just like inside called method.

In Java, this is not possible, because object references are passed by value.

A few things

  • C has no references (in spite of C++)
  • Java has no pointers
  • The difference between pointers and references is, that pointers are practically memory addresses you can calculate with. References can not be calculated with
  • Java and C pass by value (When passing an object in Java, the reference is copied to the function)

If you are studying C (rather than C++), then there are no references.

The term "pass by reference" in C simply means that you are passing a pointer as the address in which the value will be stored, so that the function can change its value. Otherwise, you're passing by value which means that a copy of the variable is generated on the stack and modifications have no impact.

In many ways this is similar to what you see in Java, except that in Java you don't have to explicitly turn things into a pointer or dereference them. In other words, when you pass a pointer, the address is copied on the stack, so if your function changes the pointer (rather than the data it points to), the changes disappear when you are done with the function. Similarly, when you pass an object reference in Java, you can change the contents of the object (e.g., by calling functions), but changing the varialbe to point at anothr object will have no effect once you leave.

If you were using C++ (which looks like C), then you can pass by reference, in which case you don't need to deal with pointers, and changes to the variable in the function actually change the external value directly (except that you can't make it point at something else).

There's a recent article by Eric Lippert about this. He's a programmer on the C# compiler, but whatever he says there has enough generality to be extended to other GC languages such as Java:

http://blogs.msdn.com/ericlippert/archive/2009/02/17/references-are-not-addresses.aspx

Quote from the article:

Pointers are strictly "more powerful" than references; anything you can do with references you can do with pointers. [...]

Pointers are typically implemented as addresses. An address is a number which is an offset into the "array of bytes" that is the entire virtual address space of the process. [...]

For all these reasons we do not describe references as addresses in the specification. The spec just says that a variable of reference type "stores a reference" to an object, and leaves it completely vague as to how that might be implemented. Similarly, a pointer variable stores "the address" of an object, which again, is left pretty vague. Nowhere do we say that references are the same as addresses.

So, in C# a reference is some vague thing that lets you reference an object. You cannot do anything with a reference except dereference it, and compare it with another reference for equality. And in C# a pointer is identified as an address.

By contrast with a reference, you can do much more with a pointer that contains an address. Addresses can be manipulated mathematically; you can subtract one from another, you can add integers to them, and so on. Their legal operations indicate that they are "fancy numbers" that index into the "array" that is the virtual address space of the process.

Those readers familiar with C/C++ have probably noticed that object references appear to be similar to pointers. This suspicion is, essentially, correct. An object reference is similar to a memory pointer. The main difference—and the key to Java’s safety—is that you cannot manipulate references as you can actual pointers. Thus, you cannot cause an object reference to point to an arbitrary memory location or manipulate it like an integer.

  • java not supported & operator then how can u get object address in java.
  • In java reference is done by object for example

MyClass object1 = new MyClass();

MyClass object2 = object1;

i.e. you might think that object1 and object2 refer to separate and distinct objects. However, this would be wrong. Instead, after this fragment executes, object1 and object2 will both refer to the same object. if you change in any one effect other.

*you cann't change the address of object after initialize i.e MyClass obj =new MyClass(); as reference in c++ , with object you can change only object instance value

Note: java provide a special feature object1 has been set to null, but object2 still points to the original object.

i m not sure about java but in C# or VB.net you can pass by value or by refrence

example passing by refrence

    static void Main(string[] args)
    {
        int x = 1;
        Foo(ref x);
        Console.WriteLine(x.ToString());//this will print 2
    }

    private static void Foo(ref int x)
    {
        x++;
    }

notice that x is equal to 1 but when you call the method Foo and passing x by refrence when x is increased by one in Foo the original value is increased too

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top