Step 1 of 5 · Reading · ~3 min
Learn
Functions and References
References vs Pointers
By the end of this lesson you can write a function that changes the caller's variables, using either a reference (int&) or a pointer (int*), and you can say which one fits a given job.
The problem: parameters are copies
Last lesson showed that void tryToDouble(int n) works on a private copy, so the caller's variable never changes. Sometimes changing the caller's variable is exactly the point. C++ gives you two tools for that.
References: a second name
A reference is another name for a variable that already exists. You declare it with & after the type, and it must be bound to a variable on the line where it is declared:
int score = 40;
int& alias = score; // alias and score are the SAME int
alias += 5;
std::cout << score << "\n"; // 45
There is no copy. Writing to alias writes to score. A reference cannot be null and cannot be re-bound to a different variable later; it names that one variable for its whole life.
The useful form is a reference parameter. The function's parameter becomes a second name for the caller's argument:
void addTo(int& total, int amount) {
total += amount;
}
int bank = 100;
addTo(bank, 25); // no & at the call site
addTo(bank, 5);
std::cout << bank << "\n"; // 130
Trace: on the first call total is bank, so bank becomes 125; on the second it becomes 130. amount has no &, so it is an ordinary copy.
Pointers: an address you follow
A pointer holds the address of a variable. &x takes the address, *p follows it to the variable:
void addToPtr(int* total, int amount) {
*total += amount; // follow the address, then add
}
int bank = 100;
addToPtr(&bank, 25); // pass the address explicitly
std::cout << bank << "\n"; // 125
Same effect, more punctuation: & at every call, * at every use. What a pointer can do that a reference cannot: hold nullptr (meaning "no variable at all"), and be pointed somewhere else later. Use a reference by default; use a pointer when "maybe nothing" or "may point elsewhere" is part of the meaning.
const references
void show(const std::string& s) shares the caller's string without copying it, and const makes the compiler reject any write to s. This is the normal way to pass a large read-only value, the same idea as const auto& in a range-for.
The trap: a reference is not a saved copy
Because a reference is the variable, it cannot remember an old value:
int level = 3;
int& before = level; // WRONG if you meant "remember 3"
level = 8;
std::cout << before << "\n"; // 8, not 3
int kept = level; // a plain int is a real copy
level = 1;
std::cout << kept << "\n"; // 8
If you need the old value after the variable changes, store it in a plain int.
Common mistakes
- Dropping the
&from the parameters. The function then swaps its own copies and the caller sees nothing: input3 7prints3 7. - Two assignments with no temporary. The first assignment overwrites one value before anything has read it, so both variables end up equal: input
3 7prints7 7. - Making the temporary a reference.
int&for the holding variable aliases one of the parameters, so it changes along with it and you get7 7again. The holder must be a plainint.
Your exercise
Fill in the body of swap(int& a, int& b) so the caller's two integers trade values. The starter already reads the numbers, calls swap, and prints them; you only write the body. The likely mistake is losing one value because nothing held it while the other moved.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…