8

I was wondering how to make a function alter two variables (the return and another one) and I stumbled upon calling the function with an '&' before the parameter (which I understand to mean the address of the parameter) then throughout your function, referencing it with the '*' sign (which I guess is a "dereference" and means it alters the object at the address).

Anyways, this was all going fine, then a friend said you can just call the function with the variable directly, refer to the variable with an & before it in the header, and treat it normally throughout the function. This seems way easier, so why isn't there more about it on the web? Is one style more correct than the other?

void foo(int &junk)  //The way the friend said
{
    junk++;
}

void oof(int *junk) //what I found, and what the internet seems full of
{
    (*junk)++;
}

int main ()
{
    int junk=1;
    std::cout << junk << "\n";
    foo(junk);
    std::cout << junk << "\n";
    oof(&junk);
    std::cout << junk;
}

This outputs:

1
2
3

So everything works fine, I'd assume.

Sean Cline
  • 6,979
  • 1
  • 37
  • 50
Jackson
  • 559
  • 7
  • 20
  • 5
    using the & in the parameter name creates a "reference variable". The classic pointer approach `void oof(int *junk)` is the only way you can do something like this in C. Many people prefer using pointers for variables when you intend to change them because it makes it more obvious to the caller that you intend to modify the variable. The reference variable approach is more commonly used with const parameters such as `void(const int & junk)` meaning the argument won't be modified. – Ryan Haining Jul 27 '13 at 16:32
  • The OP indicated that they would like [multiple return values](http://stackoverflow.com/questions/7624779/returning-multiple-data-items-from-a-function-in-c-or-c), which is not mentioned in the current answers or proposed duplicate. For that, consider something like returning a [`std::tuple`](http://en.cppreference.com/w/cpp/utility/tuple) and continuing to accept arguments as you typically would. – Sean Cline Jul 27 '13 at 17:11

2 Answers2

6

The first approach is called "passing by pointer"; the second approach is called "passing by reference". In the first case, dereference is explicit; in the second case, dereference is implicit.

The biggest difference between the two approaches is that when you pass by pointer, you can pass "nothing" (i.e. a null pointer). When you pass by reference, it is not possible to legally pass a reference to nothing: it should be a reference to some variable, an array element, a field of a class or a structure, etc.

When you need to return a value and modify a variable, passing by reference is more appropriate, because the variable that you need to modify always exists. Passing by pointer becomes more appropriate in situations when you traverse a dynamic data structure connected by pointers, when parts of that data structure may or may not exist.

Bartek Banachewicz
  • 38,596
  • 7
  • 91
  • 135
Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
  • This (accepted) answer is opposite to the higher voted answer below. Also, I would argue that "junk" is more implicit than "*junk". – so860 Feb 23 '18 at 19:41
4

The you first function foo, you are passing by reference :

When a variable is passed by reference we are not passing a copy of its value, but we are somehow passing the variable itself to the function and any modification that we do to the local variables will have an effect in their counterpart variables passed as arguments in the call to the function.

An example of passing by reference :

Passing by reference

In your second example oof, you are passing a pointer to the variable.

If you want to know the different between both example, I suggest you to read this : https://stackoverflow.com/a/57492/1394283

But, When you should use references and when you should use pointer ?

I will say use references whenever you can, use pointers whenever you must.

The reason is that pointers makes things harder to follow/read, less safe and far more dangerous manipulations than any other constructs.

This post explains it very well : https://stackoverflow.com/a/7058373/1394283

Community
  • 1
  • 1
Pierre Fourgeaud
  • 14,290
  • 1
  • 38
  • 62