← Back to C++ Course | Chapter 7: Pointers & References | Lesson 9 of 11

C++ Reference vs Pointer

References and pointers both let you reach another variable, but a reference is a permanent nickname while a pointer is a note that can be changed to point elsewhere. This topic compares when to use each.
Syntax
cpp
data_type *pointer_name = &variable_name;  // can be reassigned or nullptr
data_type &reference_name = variable_name;  // must be initialized, cannot be reseated

Syntax Differences

Pointers use an asterisk (*) for declaration and dereferencing and an ampersand (&) to retrieve a variable's address, while references use only the ampersand at declaration and then behave exactly like a normal variable, with no special dereference syntax needed afterward.

Example: Syntax Differences

cpp
// Include std::cout and std::cin
#include <iostream>

// Program execution starts in main()
int main() {
	// Declare value and set it to 5
	int value = 5;
	int *ptr = &value;
	int &ref = value;
	// Print to the console with cout
	std::cout << *ptr << " " << ref << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Nullability

Pointers can be assigned nullptr to represent an empty or not-yet-initialized state, which is essential for optional or lazily-set data.

References cannot be null — they must be bound to a valid variable the moment they're created, which rules out an entire category of null-pointer bugs.

Example: Nullability

cpp
#include <iostream>

int main() {
	int *ptr = nullptr; // valid: represents "no value"
	int value = 5;
	int &ref = value; // references must always refer to something
	std::cout << ref << std::endl;
	return 0;
}

Reassignment

Pointers can be reassigned to point to a different variable at any time during their lifetime, making them suitable for iteration and dynamic data structures.

References are bound to their target at initialization and can never be redirected to refer to anything else afterward.

Example: Reassignment

cpp
#include <iostream>

int main() {
	int a = 1, b = 2;
	int *ptr = &a;
	ptr = &b; // pointers can be reassigned
	std::cout << *ptr << std::endl;
	return 0;
}

Pass-by-Value vs Reference vs Pointer

Pass-by-value copies the argument entirely, which is safe but can be expensive for large objects. Pass-by-pointer copies just the memory address but requires the function to check for nullptr.

Pass-by-reference shares the original variable directly with clean syntax and no null-check burden.

Example: Pass-by-Value vs Reference vs Pointer

cpp
// Include std::cout and std::cin
#include <iostream>

void byValue(int x) { x = 100; }
void byReference(int &x) { x = 100; }
void byPointer(int *x) { *x = 100; }

// Program execution starts in main()
int main() {
	int a = 1, b = 1, c = 1;
	byValue(a);
	byReference(b);
	byPointer(&c);
	// Print to the console with cout
	std::cout << a << " " << b << " " << c << std::endl;
	// Return 0 to signal that the program finished successfully
	return 0;
}

Use Cases

Use references by default for clean function parameters and for operator overloading, where the syntax reads naturally.

Reach for pointers instead when you need to represent an optional/absent value with nullptr, perform pointer arithmetic, or manage memory you allocated on the heap yourself.

Example: Use Cases

cpp
#include <iostream>

void printValue(const int &x) { // reference: clean parameter syntax
	std::cout << x << std::endl;
}

int main() {
	int arr[] = {1, 2, 3};
	int *ptr = arr; // pointer: needed for array iteration
	printValue(*ptr);
	return 0;
}
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Trying to make a reference null, which is not allowed.
  2. Reassigning a reference to point to another variable.
  3. Forgetting to check a pointer for null while assuming it behaves like a reference.

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.