Pointers are not just addresses — you can do math with them. When you increment a pointer, it moves forward by the size of the data type it points to. This makes pointer arithmetic perfect for traversing arrays.
Incrementing and Decrementing
Adding 1 to an int* moves it forward by 4 bytes (the size
of an int on most systems). The compiler handles the size
calculation for you:
#include <iostream>
int main() {
int numbers[4] = {10, 20, 30, 40};
int* ptr = numbers;
std::cout << "Start: " << *ptr << "\n";
ptr++;
std::cout << "After increment: " << *ptr << "\n";
ptr++;
std::cout << "After another: " << *ptr << "\n";
ptr--;
std::cout << "After decrement: " << *ptr << "\n";
return 0;
}
Notice that ptr = numbers gives us the address of the
first element. An array name decays to a pointer to its first element.
Traversing an Array
You can loop through an array using pointer arithmetic instead of indexing. The two approaches are equivalent, but pointer arithmetic can be faster in performance-critical code:
#include <iostream>
int main() {
int arr[5] = {100, 200, 300, 400, 500};
int* start = arr;
int* end = arr + 5;
for (int* p = start; p < end; p++) {
std::cout << *p << " ";
}
std::cout << "\n";
return 0;
}
The loop runs the pointer p from the start of the array
to one past the last element. The condition p < end
stops us before we go out of bounds.
Pointer Difference
Subtracting two pointers gives you the number of elements between them:
#include <iostream>
int main() {
int data[8] = {2, 4, 6, 8, 10, 12, 14, 16};
int* first = &data[0];
int* third = &data[2];
std::ptrdiff_t diff = third - first;
std::cout << "Elements between: " << diff << "\n";
int* mid = data + 4;
std::cout << "Middle element: " << *mid << "\n";
return 0;
}
The result type is std::ptrdiff_t, a signed integer type
guaranteed to hold any valid pointer subtraction.