3
int y=5;
int *yPtr = nullptr;
yPtr = &y;

I understand that the pointer stores the address of y. and calling *yPtr dereferences y.

If I have a call to the void function:

int main()
{
    int number = 5;
    function( &number );
}

void function( int *nPtr)
{
    *nPtr = *nPtr * *nPtr;
}

if the function takes a pointer as argument, how can the call to the function use an address? I understand that nPtr stores addresses but why couldn't it be defined as.

void functions (int &ref)
{
    ref = ref * ref;
}

My main question would be: Why does a function receiving an address argument need a pointer parameter to receive the address?

user3348712
  • 161
  • 10
  • 1
    I guess that is how the standard is written. Even though references mostly work as pointers, you don't initialize them with a address, you initialize them with the value of a variable. The compiler does the same in both cases probably. – rozina Mar 06 '14 at 07:29
  • So you're asking why you need to explicitly pass an address, rather than the compiler implicitly doing it for you as it does with the pass-by-reference case? – jozxyqk Mar 06 '14 at 07:43
  • I'm wondering why the function passes an address argument but has a pointer parameter. – user3348712 Mar 06 '14 at 07:45
  • because a pointer holds an address... recall that pointer behave exactly like any other ordinary types: when we copy a pointer, the value of the pointer is copied. After the copy, the two pointers are distinct. – Victor Mar 06 '14 at 07:48
  • I think I know why I'm confused. Because I think that function is assigning *nPtr = &number, instead of nPtr = &number like the declarations at the top. Which one is right? – user3348712 Mar 06 '14 at 07:51
  • @user3348712: The function is **initializing**, not **assigning**. Initialization in your first example would look like `int *nPtr = &y;`. – MSalters Mar 06 '14 at 08:31

3 Answers3

4

By using a pass-by-reference parameter, you force your function not the copy the value of the parameter itself, instead, to use the actual variable you provide. So, for a more clear view, see below:

void function( int number )
{
  cout << number;
}

function( myInt ); // function will copy myInt, into its local variables stack

but, by using the pass-by-reference method, like this:

void function ( int & number )
{
  cout << number
}

function( myInt ); // function will not copy myInt into its local variables stack, instead, it will use the already existent myInt variable.

There is no difference in how to compiler will work with pass-by-pointer and pass-by-reference parameters. Instead, the call of your function will look like so:

void function_p( int *number )
{
  cout << *number;
}

void function_r( int & number )
{
  cout << number;
}

// and the calls

function_p( &myInt ); // it is required to use address-of operator here
function_r( myInt ); // the effect will be the same, but with less effort in writing that address-of operator

In C++11, programmers started to use pass-by-reference method, in general, ordinarily because it has an easier writing "template".


To complete the answer to your question, the * and & operators refer only to the type of the parameter, so that they create compound types. A compound type is a type that is defined in terms of another type. C++ has several compound types, two of which are references and pointers.

You can understand that they only affect the type of a variable (in our case, a parameter), by writing them in a proper way:

int* p1; // we will read this: pointer p1 points to an int
int* p2 = &var1; // we read this: pointer p2 points to int variable var1

int var1 = 12;
int& ref1 = var1; // and we read this: ref1 is a reference to var1

You can generally consider references represent a different for the same block of memory.

Victor
  • 13,914
  • 19
  • 78
  • 147
  • so the * and & operators only refer to the type of the variable not the actual value of the parameter? For visualizing reason, can I see it as: void function_p( (int *)number ) and void function_r( (int &) number ) – user3348712 Mar 06 '14 at 07:58
  • exactly. the `*` and `&` represent the method for creating compound types. for example, an `int` is an ordinary type, and `int*` is a compund type – Victor Mar 06 '14 at 08:02
  • That makes sense! I was getting confused because I thought that function_ p was assigning * number = &myInt. Now I understand int * is just the type and that number =&myInt. – user3348712 Mar 06 '14 at 08:08
0

you did mean

void functions (int &ref)
{
    ref = ref * ref;
}

that's how you use refs, avoiding all the '*'s of pointers syntax

Exceptyon
  • 1,584
  • 16
  • 23
-1

This is another of those quirky things of C++. Passing by reference is not the same as passing a pointer. When you do something like

void functions (int &ref)

You can pass an actual variables into functions (rather than pointers to them) like

int a = 12;
functions(a);

And inside the function you have no need to dereference. Notice that you are passing by reference, rather than passing a reference.

When you pass a reference, or pointer to something, you use star as such

void function( int *nPtr)

And thus you have to dereference with a *

Note also that you get the reference to a variable (or constant) by putting & in front of it, but you declare a reference or pointer by putting a * in front of it. At the same time, you dereference a pointer also by putting a * in front of it.

stack smasher
  • 443
  • 3
  • 10
  • Sorry, wrong, and your compiler should have told you that. `functions` can change `ref`, and obviously you can't change 12. And for the same reason, pass-by-reference doesn't pass an actual integer value, it passes a reference to an integer object. As for the the second part: References and pointers are 2 different things, and you are seriously confusing them – MSalters Mar 06 '14 at 08:35
  • You are right, I didnt think it through when I made the post – stack smasher Mar 06 '14 at 08:36