Pointers in C++ with Examples
Last modified - 29-07-2026
Author - Krishna Shinde
If you are learning C++, there's one topic that makes the language difficult for almost everyone: pointers. You've probably heard they're "hard," seen a wall of * and & symbols, and closed the tab.
This cpp tutorial starts from zero. Before touching syntax, you'll understand what is a pointer - not as an abstract concept, but as something concrete: an address in memory. Every example below is explained with the "what's actually happening in memory" view, so the syntax stops feeling random.
By the end of this C++ tutorial, you'll know what a pointer is, how to declare one, and how the & and * operators work - the foundation everything else about pointers is built on.
Table of Contents
What Is a Pointer in C++?
Every variable in your program lives somewhere in memory, and that "somewhere" has an address - just like every house on a street has a street address. A normal variable holds a value. A pointer is a variable that holds an address - specifically, the address of another variable.
That's the whole idea. A pointer doesn't hold data directly; it holds the location where the data lives.
Example 1: A Regular Variable vs Its Address
#include <iostream>
using namespace std;
int main() {
int age = 25;
cout << "Value of age: " << age << endl;
cout << "Address of age: " << &age << endl;
return 0;
}Output:
Value of age: 25
Address of age: 0x7ffee4a1c9acThat second line is new: the & symbol here means "address of." It's not the value 25 — it's where 25 is stored. Your own output will show a different address (memory locations vary between runs), and that's expected.

Declaring and Initializing a Pointer
To declare a pointer, you write the type it points to, followed by an asterisk, followed by the pointer's name.
Syntax:
type* pointerName;To make the pointer actually useful, you initialize it with the address of an existing variable, using &.
Example 1: Declaring a Pointer to an Integer
#include <iostream>
using namespace std;
int main() {
int age = 25;
int* agePtr = &age;
cout << "age: " << age << endl;
cout << "agePtr (address stored): " << agePtr << endl;
return 0;
}Output:
age: 25
agePtr (address stored): 0x7ffee4a1c9acagePtr is not "25." It's the address where 25 lives — the same address &age printed in Example 1.
Example 2: Pointer to a Double
#include <iostream>
using namespace std;
int main() {
double price = 19.99;
double* pricePtr = &price;
cout << "price: " << price << endl;
cout << "pricePtr: " << pricePtr << endl;
return 0;
}Output:
price: 19.99
pricePtr: 0x7ffd3c2a1b28Notice the pointer's type matches the variable it points to - double* pricePtr, not int* pricePtr. A pointer's type tells the compiler how to interpret the data at that address, so this match is required.
The Dereference Operator (*): Getting the Value Back
Once you have an address stored in a pointer, you'll often want to go to that address and read (or change) the value sitting there. That's what the * operator does when it's used on an already-declared pointer — it's called dereferencing.
This is the part that confuses people most, because * means two different things depending on where it appears:
- In a declaration (int* p) — it means "this variable is a pointer."
- In an expression (*p) — it means "go to the address p holds, and give me the value there."
Example 1: Reading a Value Through a Pointer
#include <iostream>
using namespace std;
int main() {
int age = 25;
int* agePtr = &age;
cout << "Value via pointer: " << *agePtr << endl;
return 0;
}Output:
Value via pointer: 25Example 2: Changing a Value Through a Pointer
#include <iostream>
using namespace std;
int main() {
int score = 50;
int* scorePtr = &score;
*scorePtr = 90;
cout << "score is now: " << score << endl;
return 0;
}Output:
score is now: 90This is the key moment: score itself changed to 90, even though you never wrote score = 90 directly. *scorePtr = 90 reached into memory through the address and overwrote the value sitting there. This is exactly how "pass by reference" works under the hood, and it's why pointers matter far beyond syntax exercises.
Example 3: Two Pointers, Same Variable
#include <iostream>
using namespace std;
int main() {
int total = 100;
int* p1 = &total;
int* p2 = &total;
*p1 = 200;
cout << "total: " << total << endl;
cout << "value via p2: " << *p2 << endl;
return 0;
}Output:
total: 200
value via p2: 200Both p1 and p2 point to the same address, so changing the value through one is visible through the other — they're both looking at the same memory location, not separate copies.
The Difference Between Pointer and a Normal Variable
| Aspect | Normal Variable | Pointer Variable |
|---|---|---|
| Holds | A value (e.g. 25) | An address (e.g. 0x7ffee4a1c9ac) |
| Declared as | int age; | int* agePtr; |
| Access value directly | age | *agePtr (dereference required) |
| Access its address | &age | &agePtr (address of the pointer itself) |
| Size in memory | Depends on type (int = 4 bytes, double = 8 bytes, etc.) | Fixed size (typically 8 bytes on 64-bit systems), regardless of type pointed to |
Null Pointers: A Pointer That Points to Nothing
A pointer doesn't have to point to a variable. When it isn't pointing anywhere valid yet, it's good practice to set it to nullptr rather than leaving it uninitialized — an uninitialized pointer holds a garbage address, and dereferencing it can crash your program or corrupt memory silently.
Example: Declaring and Checking a Null Pointer
#include <iostream>
using namespace std;
int main() {
int* ptr = nullptr;
if (ptr == nullptr) {
cout << "ptr is not pointing to anything yet." << endl;
}
int value = 42;
ptr = &value;
if (ptr != nullptr) {
cout << "ptr now points to a value: " << *ptr << endl;
}
return 0;
}Output:
ptr is not pointing to anything yet.
ptr now points to a value: 42Important: Always check a pointer against nullptr before dereferencing it if there's any chance it hasn't been assigned a valid address. Dereferencing a null or uninitialized pointer is one of the most common bugs in a C++ tutorial on pointers — and one of the most common causes of crashes in real C++ programs.
Conclusion
A pointer is nothing more than a variable that stores an address instead of a value. Once that idea is solid, the syntax stops being scary: & gets you an address, * in a declaration marks a variable as a pointer, and * in an expression dereferences a pointer to reach the value it points to.
This is Part 1 — the "what pointers are" foundation. Part 2 will build on this with pointer arithmetic, pointers and arrays, and pointers to pointers, so make sure the ideas here — address vs value, and the two meanings of * — feel comfortable before moving on.
Keep practicing by tweaking these examples: declare your own pointers, dereference them, change values through them, and print both the value and the address at each step. That kind of hands-on repetition is exactly what makes pointers stick in coding tutorials, and it's the same habit that will make the rest of your C++ language tutorial journey much easier.