I work in an undergraduate T.A. role for a computer science sequence that teaches students programming concepts and data structures in C++. In each course, students have to take a proficiency demo — a closed book, closed notes, live coding exam where they must solve a technical interview-flavored question with a given data structure. For the students in the latter half of the sequence, their solutions must be recursive and they may not use regular loops of any kind. Nothing like throwing a wrench into the specifications, right?

One of the most common mistakes that I see students make when programming in C++ is passing a pointer by value (with the intent of pointing it elsewhere for the calling routine) or not knowing when to pass some other data type by reference (like a class object).

Pass by reference is something that seems to fall by the wayside compared to their other learning goals; but it really shouldn’t! Passing a reference in C++ can make crafting recursive algorithms just a little more convenient. Not to mention, depending which standard of C++ you’re working with, you may not have move semantics or the default copy constructor (if you didn’t provide one) may come back to bite you. Personally, I think it’s worth it to learn a more modern standard of C++; but I digress.

Languages like Java or C don’t directly have pass-by-reference. In Java, you pass a reference by value. This is exactly like passing a pointer by value in C. There are workarounds, of course, but that’s beside the point for now.

My intent with this article is to provide clarification on how passing variables by value is different by reference; with a particular bias towards exploring passing pointers by reference as well. I also assume that you know what recursion is.

## Passing by value

Chances are, you pass variables by value all the time. This is normal. We all do. When you pass a variable by value, a copy is made and that copy is given to the function you just called. Consider the following function:

```void addFive(int x)
{
x += 5;
std::cout << "I added 5: " << x << "\n";
}
```

This function seems pretty straight forward. It adds 5 to the parameter named `x` and displays a triumphant message detailing our arithmetic prowess.

Here’s my main function:

```int main()
{
int x = 10;

addFive(x);

std::cout << "x = " << x << "\n";

return 0;
}
```

What’s the output? Did my variable `x` in the `main()` function change its value after the `addFive()` function call?

```I added 5: 15
x = 10
```

No, it doesn’t. It’s because we passed our variable by value. Our `addFive()` function received a copy of the variable that we passed into it when we called it in `main()`. We modified the copy, not the actual variable that lives in `main()`.

If we want to modify the variable passed in to our function by the calling routine (aka, the `x` variable that lives in `main()`) we either need to return the new value, or change our function signature to take the variable by reference.

## What is a reference?

I’m so glad you asked. A reference is an alias. Kind of like a pen name. Dr. Seuss is Theodor Seuss Geisel’s pen name, or his alias. Dr. Seuss and Geisel are the same person. When Dr. Seuss wrote a draft, that means that Geisel wrote the draft. This seems blatantly obvious, but this applies to C++ too!

In this context, a reference is a “pen name” for a variable. If the “pen name” does something or is modified, the original variable is changed too.

If you need a darker/more mystical example, think of a reference as a voodoo doll, and the variable that it references is the victim.

More concretely, you can think of a reference in C++ as a pointer that is already dereferenced (`*myPtr = 43` == `myRef = 43`).

Let’s see it in action.

```int main()
{
int x = 10;
std::cout << "x = " << x << "\n";

int&amp; penName = x; // Notice the &amp;! This means it is a REFERENCE variable
penName += 10;
std::cout << "Now, x = " << x << "\n";

return 0;
}
```

What do you think the output is?

```x = 10
Now, x = 20
```

Notice that we modified the reference and that modification is reflected in the variable we referenced!

If you’re curious what our function signature would look like (from the previous section), it’d look like this:

```void addFive(int& x) { . . . }
```

## Passing pointers by reference

Let’s consider this recursive function:

```int append(Node*& head, int data)
{
if (!head) {
head = new Node;
head->data = data;
head->next = nullptr;
return 1;
}
return append(head->next, data);
}
```

This function appends a `Node` to the end of a linear linked list. Would this work if we passed the pointer by value? Not in its current state. We would run into the same problem as before with `addFive()`. We would be modifying what the copy points to, not what the original pointer points to.

Passing a pointer by reference in this case solves that problem and it also gives us some degree of convenience–it automates the “linking” of the list.

Let’s assume we call this function on an empty list (`nullptr`).

```int main()
{
Node* head = nullptr;

append(head, 1);

return 0;
}
```

That’s simple, our base case is triggered immediately and we point it at a newly allocated Node. Since we passed the Node pointer in by reference, it automatically assigns the original head pointer from `main()` to point at the new Node.

Okay, let’s do it again.

```int main()
{
Node* head = nullptr;

append(head, 1);
append(head, 2);

return 0;
}
```

As we saw before, the first `append()` call creates the first Node and points our `head` pointer at it because our `head` variable in `main()` is initialized to `nullptr`.

In the second call, `head` is not `nullptr`, so we recurse, passing in `head`‘s next by reference. Since there’s only the one node, `head`‘s next pointer is `nullptr` and when we enter the second recursive call, our base case triggers, and we create a new Node and point our stack frame’s `head` to it.

Our current stack frame’s `head` pointer is our previous stack frame’s `next` pointer! Thus, it is automatically linked because we passed in our `next` pointer by reference!

See how easy it is? This makes for some concise, self-sufficient recursive functions. Try to practice recursion in C++ with this.

For posterity, here is the same function without pass-by-reference:

```Node* appendByValue(Node* head, int data)
{
if (!head) {
head = new Node;
head->data = data;
head->next = nullptr;
return head;
}

head->next = appendByValue(head->next, data);
return head;
}
```

And here’s what it looks like in use:

```int main()
{
Node* head = nullptr;

append(head, 1);
head = appendByValue(head, 2);

return 0;
}
```

Try to work your way through this after you’ve spent some time with the other version and trace the steps of the algorithm. Drawing diagrams certainly helps illustrate the differences and demonstrate what is happening.