C++: Pointers and Arrays
Last updated: 2026-08-26
In Lesson 16, we learned about arrays, but we didn't discuss what an array name actually is.
In fact, an array name is a pointer — it stores the address of the array's first element.
Understanding this helps explain why arrays "decay into pointers" when passed as parameters.
1. The Array Name is a Pointer
(1) 1.1 The Basic Fact
An array name is a pointer to the first element.
#include <iostream>
int main() {
int arr[5] = {10, 20, 30, 40, 50};
std::cout << "arr = " << arr << std::endl;
std::cout << "&arr[0] = " << &arr[0] << std::endl;
// Both output the same! Because arr is &arr[0]
return 0;
}
Output (example):
arr = 0x7ffd4a3b
&arr[0] = 0x7ffd4a3b
💡 Key point: arr and &arr[0] are the same address.
2. Accessing Array Elements with Pointers
(1) 2.1 Basic Usage
#include <iostream>
int main() {
int arr[5] = {10, 20, 30, 40, 50};
int* p = arr; // p points to first element
// Method 1: Subscript(same as array)
std::cout << "arr[0] = " << p[0] << std::endl; // 10
std::cout << "arr[1] = " << p[1] << std::endl; // 20
// Method 2: Dereference
std::cout << "*p = " << *p << std::endl; // 10
std::cout << "*(p+1) = " << *(p+1) << std::endl; // 20
return 0;
}
💡 Key point: p[i] is actually *(p+i) (pointer arithmetic will be explained later).
3. Pointer Arithmetic
(1) 3.1 Adding/Subtracting Integers from Pointers
When adding or subtracting an integer from a pointer, it doesn't simply add/subtract the address value — it adds/subtracts integer × sizeof(type) bytes.
#include <iostream>
int main() {
int arr[5] = {10, 20, 30, 40, 50};
int* p = arr; // Pointing to arr[0]
std::cout << "p = " << p << std::endl; // Assume 0x1000
std::cout << "p + 1 = " << p + 1 << std::endl; // 0x1004(Not 0x1001!)
std::cout << "p + 2 = " << p + 2 << std::endl; // 0x1008
return 0;
}
How it works:
inttakes 4 bytesp + 1actually adds1 × 4 = 4bytes- So
p + 1points toarr[1]
(2) 3.2 Pointer Subtraction
Subtracting two pointers gives the distance between them (number of elements), not the number of bytes.
#include <iostream>
int main() {
int arr[5] = {10, 20, 30, 40, 50};
int* p1 = &arr[0]; // Pointing to arr[0]
int* p2 = &arr[3]; // Pointing to arr[3]
std::cout << "p2 - p1 = " << p2 - p1 << std::endl; // 3(Number of elements)
return 0;
}
💡 Key point: Subtracting pointers only makes sense when they point to elements of the same array.
4. Traversing an Array with Pointers (Three Methods)
▶ Example 1: Traversing an Array (Difficulty ⭐)
#include <iostream>
int main() {
int arr[5] = {10, 20, 30, 40, 50};
// Method 1: Subscript(Most common)
std::cout << "Method 1: Subscript" << std::endl;
for (int i = 0; i < 5; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
// Method 2: Pointer arithmetic
std::cout << "Method 2: Pointer arithmetic" << std::endl;
for (int* p = arr; p < arr + 5; p++) {
std::cout << *p << " ";
}
std::cout << std::endl;
// Method 3: Use standard library function (will learn later)
// std::cout << "Method 3: std::begin/end" << std::endl;
// for (int* p = std::begin(arr); p != std::end(arr); p++) {
// std::cout << *p << " ";
// }
return 0;
}
Output:
Method 1: Subscript
10 20 30 40 50
Method 2: Pointer arithmetic
10 20 30 40 50
💡 Recommendation: Method 1 (subscript) is the most intuitive — prefer it. Method 2 (pointer arithmetic) is common in low-level code.
5. Array Decay When Passed as a Parameter
(1) 5.1 The Problem: Arrays Decay into Pointers
When you pass an array to a function, it decays into a pointer (losing size information).
#include <iostream>
void printSize(int arr) {
// arr is actually a pointer, not an array!
std::cout << "sizeof(arr) = " << sizeof(arr) << std::endl; // 8(64-bit system, pointer size)
}
int main() {
int arr[5] = {10, 20, 30, 40, 50};
std::cout << "sizeof(arr) = " << sizeof(arr) << std::endl; // 20(5 x 4 = 20 bytes)
printSize(arr);
return 0;
}
💡 Key point: Inside the printSize function, arr is actually a pointer, so sizeof(arr) returns the pointer size (8 bytes), not the array size (20 bytes).
(2) 5.2 Solution: Pass the Array Size
#include <iostream>
// Must additionally pass array size
void printArray(int arr, int size) {
for (int i = 0; i < size; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
}
int main() {
int arr[5] = {10, 20, 30, 40, 50};
printArray(arr, 5); // Pass array name (which is first element address)
return 0;
}
💡 Tip: Later you'll learn std::array and std::vector, which preserve size information and are safer.
6. Practice: Reversing an Array
▶ Example 2: Reversing an Array with Pointers (Difficulty ⭐⭐)
#include <iostream>
void reverseArray(int* arr, int size) {
int* left = arr; // Pointing to first element
int* right = arr + size - 1; // Pointing to last element
while (left < right) {
// Swap values pointed to by left and right
int temp = *left;
*left = *right;
*right = temp;
left++; // Move right
right--; // Move left
}
}
int main() {
int arr[5] = {10, 20, 30, 40, 50};
std::cout << "Before reversal: ";
for (int i = 0; i < 5; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
reverseArray(arr, 5);
std::cout << "After reversal: ";
for (int i = 0; i < 5; i++) {
std::cout << arr[i] << " ";
}
std::cout << std::endl;
return 0;
}
Output:
Before reversal: 10 20 30 40 50
After reversal: 50 40 30 20 10
7. Common Errors
(1) 7.1 Pointer Out of Bounds
#include <iostream>
int main() {
int arr[5] = {10, 20, 30, 40, 50};
int* p = arr;
std::cout << *(p + 10) << std::endl; // ❌ Out of bounds! p+10 points outside array
// Outputs garbage value, or program crashes
return 0;
}
💡 Tip: C++ does not automatically check pointer bounds! This is one reason C++ is fast, but also a common source of bugs.
(2) 7.2 Pointer Subtraction Without Meaning
#include <iostream>
int main() {
int x = 5;
int y = 10;
int* p1 = &x;
int* p2 = &y;
std::cout << p2 - p1 << std::endl; // ❌ Undefined behavior! p1 and p2 point to different arrays
// Only subtracting pointers to the same array is meaningful
return 0;
}
❓ FAQ
arr and &arr have the same value but different types?arr has type int* (pointer to int) > - &arr has type int(*)[5] (pointer to "array of 5 ints")* and /?p + n, p - n) > - Subtract two pointers (p2 - p1) > - Compare (p1 < p2)▶ Example 3: Traversing an Array with Pointers (Difficulty ⭐)
#include <iostream>
int main() {
int arr[] = {10, 20, 30, 40, 50};
int* p = arr;
for (int i = 0; i < 5; i++) {
std::cout << "*(p+" << i << ")=" << *(p + i) << std::endl;
}
return 0;
}
Output:
*(p+0)=10
*(p+1)=20
*(p+2)=30
*(p+3)=40
*(p+4)=50
*(p + i) is equivalent to p[i] or arr[i]. Adding/subtracting integers from pointers automatically accounts for the type size.
- Array names are pointers (pointing to the address of the first element)
- Adding/subtracting integers from pointers adds
integer × sizeof(type)bytes - Subtracting two pointers gives the number of elements between them, not bytes
- Arrays decay into pointers when passed as parameters; you need to pass the size separately
- There are three methods for traversing arrays with pointers: subscript, pointer arithmetic, standard library functions
📖 Summary
- Array name: address of the first element, equivalent to a pointer
- Pointer traversal:
*(p + i)is equivalent top[i] - Array as parameter: decays to pointer, requires passing length separately
- Multi-dimensional arrays: traversed using pointers to arrays
📝 Exercises
-
Basic (Difficulty ⭐): Declare an
intarrayarr[5] = {1, 2, 3, 4, 5}, then declare anint*pointerppointing toarr. Output all elements using the pointer. -
Intermediate (Difficulty ⭐⭐): Write a function
int* findElement(int* arr, int size, int target)that searches for a target value in an array. If found, return a pointer to that element; if not found, returnnullptr. -
Challenge (Difficulty ⭐⭐⭐): Write a program that implements "bubble sort" using pointers:
-
Traverse the array, comparing adjacent elements
-
If they're in the wrong order, swap them
-
Repeat this process until the array is sorted
- Array names are constant pointers (address of the first element)
- Pointer arithmetic: p + n offsets by n elements, not n bytes
- Array subscript access arr[i] is equivalent to *(arr + i)
- Traversing arrays with pointers is more flexible than subscripts
- Arrays decay to pointers when passed as function parameters
12. 🚀 Next Step
Now that you've learned about pointers and arrays, let's move on to Advanced Pointer Arithmetic (Lesson 24) — a deeper look at pointer types, void* pointers, and multi-level pointers.