Skip to content
C++ Better Explained
Go back
C++ Reference vs Pointer: What's the Difference?
Edit page

C++ Reference vs Pointer: What’s the Difference?

Both references and pointers let you work with variables indirectly — but they have different rules, different syntax, and different appropriate uses. If you already understand pointers, references are easy to learn by comparison.


The Basic Syntax

Pointer:

int x = 10;
int* p = &x;    // p holds the address of x
*p = 20;        // dereference to change x
cout << x;      // 20

Reference:

int x = 10;
int& ref = x;   // ref is an alias for x
ref = 20;       // changes x directly — no dereference needed
cout << x;      // 20

The reference ref and the variable x are the same thing — just different names for the same memory location.


The Key Differences

1. Initialization

References must be initialized when created:

int* p;        // OK — uninitialized pointer (dangerous but legal)
int& ref;      // Error — references must be initialized
int& ref = x; // Must bind immediately

2. Nullability

Pointers can be null; references cannot:

int* p = nullptr;  // Valid — a null pointer
int& ref = ???;    // No such thing as a null reference

3. Reassignment

Pointers can point to different objects; references cannot be rebound:

int a = 1, b = 2;

int* p = &a;
p = &b;         // p now points to b — fine

int& ref = a;
ref = b;        // This does NOT rebind ref — it assigns b's VALUE to a
                // ref still refers to a, and a is now 2

4. Syntax for Access

Pointers require * to dereference and -> for members; references use the same syntax as the original variable:

struct Point { int x, y; };

Point pt = {3, 4};

// Pointer
Point* pp = &pt;
cout << pp->x;   // Arrow operator for member access
cout << (*pp).x; // Equivalent — dereference then member access

// Reference
Point& pr = pt;
cout << pr.x;    // Same syntax as pt.x — no dereferencing needed

5. Memory Address

References don’t have their own address (from a conceptual standpoint). Getting the address of a reference gives the address of the original object:

int x = 42;
int& ref = x;

cout << &x;    // Same address
cout << &ref;  // Same address — they're the same object

Using References in Function Parameters

This is the most common use of references — passing by reference to avoid copying and to allow modification:

// Pass by value: function gets a copy (changes don't affect original)
void doubleVal(int x) {
    x *= 2;
}

// Pass by pointer: works, but caller must pass &variable, function must use *
void doublePtr(int* x) {
    *x *= 2;
}

// Pass by reference: cleanest — no pointer syntax, can't be null
void doubleRef(int& x) {
    x *= 2;
}

int n = 5;
doubleVal(n);   // n is still 5
doublePtr(&n);  // n is now 10
doubleRef(n);   // n is now 10 (after resetting)

References are preferred for function parameters because:


const References

One of the most important patterns in C++: pass by const reference to avoid copying without allowing modification:

// Passes a copy — slow for large objects
void print(string s) { cout << s; }

// Passes by const reference — no copy, no modification allowed
void print(const string& s) { cout << s; }

string bigString(1000000, 'x');  // 1 million characters
print(bigString);  // const ref version: no copy made

const string& is the standard way to pass strings, vectors, and other large objects to functions that don’t need to modify them.


When to Use Each

Use references when:

Use pointers when:

If you're looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you're a complete beginner or looking to solidify your understanding. Just $19.

Practical Example: Swap Function

// With pointers (C style)
void swapPtr(int* a, int* b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

swapPtr(&x, &y);  // Must pass addresses

// With references (C++ style)
void swapRef(int& a, int& b) {
    int temp = a;
    a = b;
    b = temp;
}

swapRef(x, y);  // Pass variables directly — cleaner

Summary Table

FeaturePointerReference
Syntaxint* p = &x;int& r = x;
Can be nullYes (nullptr)No
Initialization requiredNoYes
Can be reassignedYesNo
Access memberp->memberr.member
Get addressp (is the address)&r (same as original)
ArithmeticYesNo
Use for functionsvoid f(int* p)void f(int& r)


Take Your C++ Further

If you’re looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you’re a complete beginner or looking to solidify your understanding. Just $19.

👉 Get the C++ Better Explained Ebook — $19

📋

Free Download: The 10 Mistakes Every C++ Beginner Makes

A free 1-page checklist that shows the exact traps that slow down every C++ beginner — so you can avoid them from day one.

🔒 No spam. Unsubscribe anytime.


Edit page
Share this post on:

Previous Post
C++ Namespace Tutorial: using namespace std Explained
Next Post
C++ Segmentation Fault: What It Is and How to Fix It