C++ Reference vs Pointer
In this page:
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
// 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;
}
Login to try C/C++/Java/PHP code in the editor
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
#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;
}
Login to try C/C++/Java/PHP code in the editor
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
#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;
}
Login to try C/C++/Java/PHP code in the editor
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
// 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;
}
Login to try C/C++/Java/PHP code in the editor
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
#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;
}
Login to try C/C++/Java/PHP code in the editor
- Trying to make a reference null, which is not allowed.
- Reassigning a reference to point to another variable.
- Forgetting to check a pointer for null while assuming it behaves like a reference.
Chapter Quiz — Complete all 11 topics to unlock
0/11 topics done
Complete these topics first: