Here is where I learned pointers: https://cplusplus.com/doc/tutorial/pointers/
Once you understand pointers, pointer arithmetic is easy. The only difference between it and regular arithmetic is that the number you are adding to the pointer will be multiplied by the size of the type that the pointer is pointing to. For example, if you have a pointer to an int and an int's size is 4 bytes, (pointer_to_int + 4) will evaluate to a memory address 16 bytes (4 ints) ahead.
So when you write
(a_pointer + a_number)
in pointer arithmetic, what's really happening is
(a_pointer + (a_number * sizeof(*a_pointer)))
in regular arithmetic.
Answer from Paige Ruten on Stack Overflowc - Pointer Arithmetic - Stack Overflow
Why Does Pointer Arithmetic Work The Way It Does?
When performing pointer arithmetic, does the type matter?
Pointer Arithmetic
Can I perform arithmetic on function pointers in C?
Can I use pointer arithmetic with strings?
Why does pointer arithmetic depend on data type?
Here is where I learned pointers: https://cplusplus.com/doc/tutorial/pointers/
Once you understand pointers, pointer arithmetic is easy. The only difference between it and regular arithmetic is that the number you are adding to the pointer will be multiplied by the size of the type that the pointer is pointing to. For example, if you have a pointer to an int and an int's size is 4 bytes, (pointer_to_int + 4) will evaluate to a memory address 16 bytes (4 ints) ahead.
So when you write
(a_pointer + a_number)
in pointer arithmetic, what's really happening is
(a_pointer + (a_number * sizeof(*a_pointer)))
in regular arithmetic.
First, the binky video may help. It's a nice video about pointers. For arithmetic, here is an example:
int * pa = NULL;
int * pb = NULL;
pa += 1; // pa++. behind the scenes, add sizeof(int) bytes
assert((pa - pb) == 1);
print_out(pa); // possibly outputs 0x4
print_out(pb); // possibly outputs 0x0 (if NULL is actually bit-wise 0x0)
(Note that incrementing a pointer that contains a null pointer value strictly is undefined behavior. We used NULL because we were only interested in the value of the pointer. Normally, only use increment/decrement when pointing to elements of an array).
The following shows two important concepts
- addition/subtraction of a integer to a pointer means move the pointer forward / backward by N elements. So if an int is 4 bytes big, pa could contain 0x4 on our platform after having incremented by 1.
- subtraction of a pointer by another pointer means getting their distance, measured by elements. So subtracting pb from pa will yield 1, since they have one element distance.
On a practical example. Suppose you write a function and people provide you with an start and end pointer (very common thing in C++):
void mutate_them(int *begin, int *end) {
// get the amount of elements
ptrdiff_t n = end - begin;
// allocate space for n elements to do something...
// then iterate. increment begin until it hits end
while(begin != end) {
// do something
begin++;
}
}
ptrdiff_t is what is the type of (end - begin). It may be a synonym for "int" for some compiler, but may be another type for another one. One cannot know, so one chooses the generic typedef ptrdiff_t.
I have always found C's pointer arithmetic to be a little unintuitive.
For instance, if you have a int * that pints to 0x4 and then you add 0x1, the result will be 0x8, instead of the expected (at least for me) 0x5. This is because the value added is multiplied with the size of the base type.
Does anyone now why C does this? Especially since it has the [] operator which does the same thing, but seems more explicit. It just seems like a weird implicit behavior to tack onto the + operator. Is there any historical or technical reason?
Thank you!