Reading — step 1 of 5
Learn
References vs Pointers
C has one tool for "let a function touch the caller's data": the pointer, with its &x at every call and *p at every use. C++ kept pointers and added references — the same power with the ceremony removed — and knowing when each is right is a real C++ fluency marker. This is the chapter's payoff lesson.
References: an alias, not an address
int x = 5;
int& r = x; // r IS x now — another name for the same bytes
r = 10;
std::cout << x; // 10 — no * needed, no & at use sites
A reference is a second name for an existing variable. No dereferencing syntax, no null state, no re-seating — a reference must be initialized at birth and refers to that one variable forever. Less flexible than a pointer, and that's the selling point: a int& in your hands is guaranteed to be a live int, no checks required.
The function-parameter form is where they earn their keep:
void doubleIt(int& n) { // n aliases the CALLER's variable
n *= 2;
}
int x = 5;
doubleIt(x); // no & at the call! Clean.
std::cout << x; // 10
Compare C's version — doubleIt(&x) with *n *= 2; inside — same machine code, half the punctuation. The trade: in C++, the call site doesn't show that x may change; the signature does. That's why modern style pairs reference parameters with good naming, and why the next form matters even more:
const references: the free-lunch parameter
void printAll(const std::string& s) { // no copy, no mutation possible
std::cout << s << "\n";
}
Passing big objects by value copies them; passing by const& shares them read-only — no copy, compiler-enforced safety. This is the default way to pass anything bigger than a few bytes (std::string, vector, your structs): const T& in, value out. You met it in range-fors (const auto&); it's the same idea, everywhere.
So when pointers?
Pointers still own three jobs references can't do: optionality (a pointer can be nullptr = "no target"; a reference always has one), re-seating (a pointer can point somewhere else later), and arithmetic/arrays (walking memory is pointer work). The modern guideline in one line: references by default; pointers when "maybe nothing" or "which one may change" is part of the meaning. You'll recognize C++ written before this consensus — pointer-heavy — and after; both compile, one reads better.
Your exercise: Swap
The kata that proves the mechanism:
void swap(int& a, int& b) {
int tmp = a;
a = b;
b = tmp;
}
// in main:
swap(x, y); // just names — x and y really trade values
Put it side by side with the C version (swap(int *a, int *b) with three *s and a &x, &y call) and the design intent of references is the whole diff. One footnote for honesty: the standard library already ships std::swap — which is why the exercise wants yours named and called explicitly; write your own, watch it work, and know that under every reference is the same address machinery you'd write by hand in C. Same bytes, better manners.
Discussion
Ask a question, share an insight, or help someone who’s stuck.
Sign in to post a comment or reply.
Loading…