Skip to content
References vs Pointers
step 1/5

Reading — step 1 of 5

Learn

~3 min readFunctions and References

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…

References vs Pointers — C++ Fundamentals