I'm new to coding and am currently trying to learn C++ myself. I just learned about function parameters and pass by value vs pass by reference. Everywhere I read, they say that one of the reasons pass by reference is useful is because it allows you to change the value of an argument inside the function. But why does making the parameter variable a reference let you do that? And why can't you do that if you pass a value instead?
2 Answers
Let’s say you have a variable int x in your function. You call a function with a parameter int i, like
f(x);
You passed a value. Inside the function f the parameter is turned into a variable, as if you wrote
void f(int param_i) {
int i = param_i;
…
}
You can change i, but it is just a variable inside that function and changing it doesn’t affect x.
Now instead you write
void f(int& i) {
…
}
The parameter i is a reference to what you passed in. A call
f(x);
passes x as a reference, which means every time that f reads or writes its parameter i, it really writes the callers variable x.
Whether that is a good thing depends on what you want. If you want a call to f() to change the variable you pass in, it’s a good thing. If you had no intention that x should ever be changed by calling f(x) then it is a bad thing, and a call changing x could be a very well-hidden bug. So just because someone says “call by reference is good”, that’s not advise you should take unless you understand the consequences and the consequences are what you want.
Going back to the good old analogy of notes written on bits of paper and put in pockets.
Call by value
int i = 42;
This means "find a new bit of paper, write "42" on it, and put it in a pocket of my coat labelled i
".
void f(int j)
{
j = j + 1;
}
f(i);
When we call f(i)
, pass by value means "look in the pocket labelled i
and find whatever's written on the piece of paper there. Now get a new bit of paper and copy the value (42) onto that bit of paper. Put the new bit of paper in a pocket labelled j
.
j = j + 1
means "look in the pocket labelled j
, find the bit of paper in there, and replace the value with one greater and put that back in the pocket labelled j
. The bit of paper in j
now has "43" written on it.
At the end of f
, we throw away whatever we had in the pocket labelled j
.
We can now if we wish look at the pocket labelled i
. It's still got 42 written on it.
Call by reference
void g(int &k)
{
k = k + 1;
}
g(i);
In this case when we call g
, instead of copying "42" onto the new bit of paper we instead write i
on the bit of paper, letting us know we have to use that pocket instead.
k = k + 1
now says:
- Look in the pocket labelled
k
. We find this saysi
so we now dereference and look in the pocket labelledi
, giving us 42. k + 1
gives us 43.- We now once again look in the pocket labelled
k
, find that still saysi
and update pocketi
with the new value, 43.
At the end of g
we again throw away the contents of pocket k
.
Looking in pocket i
we see this time the bit of paper has "43" written on it.