9

I've never had problems with references as in Python (implicit) or PHP (explicit &). In PHP you write $p = &$myvar; and you have $p as a reference pointing to $myVar.

So I know in C++ you can do this:

void setToSomething( int& var )
{
 var = 123;
}
int myInt;
setToSomething( myInt );
  • myInt is now 123, why?

Doesn't & mean "memory address of" x in C++? What do I do then if var is only the address to myInt and not a pointer?

void setToSomething( int* var )
{
 *var = 123;
}
int myInt;
int* myIntPtr = &myInt;
setToSomething( myIntPtr );
  • Does the above work as expected?

I don't understand the difference between * and & in C++ fully. They tell you & is used to get the address of a variable, but why does that help you in functions etc. Like in the first example?

Alex Bravo
  • 1,601
  • 2
  • 24
  • 40
gnm
  • 113
  • 1
  • 1
  • 4

5 Answers5

29

Doesn't & mean "memory address of" x in C++?


Short answer: That depends.


Longer answer: The unary prefix operator &, when applied to an object, indeed yields the address of the object: &obj. There is, however, also the type modifier &, which, when applied to a type, will modify it to be a reference type: int&.

The same applies to *: When used as a unary prefix operator, it will dereference a pointer: *ptr. When used as a type modifier, it will modify the type to be a pointer: int*.

It's not helpful either that type modifiers apply to the variable that is declared. For example, this

int *p, **pp, i, &r = i; 

defines an int pointer, a pointer to a pointer to an int, a vanilla int, and an int reference. (The latter is immediately initialized, because you cannot have an uninitialized reference.) Note that the type modifiers syntactically belong to the declared variable whose type they are modifying, not to the declared variable's type. Nevertheless, type modifiers (* and &) modify the type of the variable.
In the following case, however, with pp and i presumed to be variables that have already been declared

*pp = &i;

* and & are unary prefix operators dereferencing pp and yielding the address of i.

(In the same vein, the type modifier [] when applied to a variable that's being declared, will modify the variable's type to an array, while the binary infix operator [], when applied to an object of array type will access one of its sub-objects.)


To complicate things even further, besides the type modifiers and the unary prefix operators & and *, there are also the binary infix operators & and *, meaning "bitwise AND" and "multiplication". And to add insult to injury, in C++ you can overload both the unary prefix and the binary infix variants of these operators (and the binary infix []) for user-defined types and be completely free as to their semantics.

sbi
  • 219,715
  • 46
  • 258
  • 445
12

In the first example, & is used to declare a reference type. It's not the same thing as the & operator which is used to get an object's address.

You can view a reference type as a type which uses under the covers a pointer which can never be NULL.

Bastien Léonard
  • 60,478
  • 20
  • 78
  • 95
  • So why use pointers when I can have reference types everywhere? – gnm Apr 19 '10 at 12:46
  • 4
    @gnm: You can do things, evil things, with pointers that you can't with references. Sometimes those are necessary. – Donal Fellows Apr 19 '10 at 12:49
  • @gnm in c/c++ pointers are often used in the performance vs safety tradeoffs. Especially in image manipulation, using (wisely) pointers will give you the ultimate performance – Vivek Bernard Apr 19 '10 at 12:52
  • 9
    @gnm: The advantage of pointers over references is that you can later reset them to point to some other object. That makes them more flexible. The advantage of references over pointers is that they cannot be reset to point to any other object than the one they were initialized with. Since this includes that they cannot (well, it's harder to have them) point to a no longer existing object, that makes them safer. – sbi Apr 19 '10 at 13:00
  • 3
    @Vivek: I don't see how using pointers would give you a speed advantage over references. – sbi Apr 19 '10 at 13:02
  • @sbi: I agree. Since references are almost certainly implemented as pointers by the compiler, the exact same code should be output by the compiler for both the reference andf the pointer version. – KeithB Apr 19 '10 at 13:38
  • 2
    @sbi is perfectly right about one advantage of pointers. Here's another: You can have several levels of indirection, i. e. pointers to pointers. That's not possible with references (you can't take the address of a reference, only of the thing the reference points to). Of course, several levels of indirection tend to knot brains, so they should be used sparingly, however, there are circumstances where they are *really* handy. Searching and removing entries from a linked list, for example. – cmaster - reinstate monica Jun 02 '15 at 20:01
3

Actually, the &-operator serves two purposes as posted above.

the first purpose is dereference, which is used like this:

int i = 123; //declare an integer variable named i with the value of 123
int *pI = &i; //declare an pointer-to-integer 
              //variable name pI pointing to the memory address of i

The &-operator is used in the meaning 'give me the memory address of'

the second purpose is to emulate call-by-reference (which c does not have natively)

a declaration like

void foo(int& theInt)
{
  theInt = 123;
}

will make the function foo accept an int parameter, to which any modification during the execution of foo is passed back.

Without the &-operator, modifications to theInt would be made in the foo's scope only and discarded once the function terminates.

sum1stolemyname
  • 4,506
  • 3
  • 26
  • 44
1

& is used in functions when you need to return more than one variable value unlike the return statement which returns a single variable.

cpx
  • 17,009
  • 20
  • 87
  • 142
0

In the second example it should be

*var = 123

Think of the ampersand in the argument declaration as the var keyword in Pascal, it's used to specify that the variable will be updated if changed. I'm not sure if the C++ semantics specify that it will be passed always by reference or it could be done via a pass by value and copy on return if it's more efficient for a given case...

fortran
  • 74,053
  • 25
  • 135
  • 175