Another possible way to do pointer arithmetic is to subtract one pointer from another. Again, let's go back to the example where we have the four integers in a row at addresses 0x4b14, 0x4b18, 0x4b1b, and 0x4b1f. Let's say we have four pointers, ptr1, ptr2, ptr3, and ptr4, each pointing at the addresses in order. With normal arithmetic, ptr4 - ptr1 would result in the number 12 meaning that there are twelve bytes between them. However, with pointer arithmetic the computer takes into account the size of the data type involved, in this case an int. As such, ptr4 - ptr1 actually results in the value 3, meaning that the two values are separated by 3 integers.

Enough stalling. What do you mean they're the same?

In the C/C++ language, pointers and arrays are closely related. As it turns out, an array is just a series of variables laid out in a sequence, one after the other. If you were to declare an array of four integers, you would end up with a situation very similar to the one described above.

As a starting example, let's declare a few variables:

int arr[4]; int *ptr;
We know that to access individual elements of an array we use the [] operator. For example, to access the first element of the array arr we would do arr[0]; to access the next element, arr[1], and so forth.

Like any other integer, we can use the & operator to get the address of an element in the array. For example, to get the address of the first element in the array, we could do &arr[0] and to get the address of the last element in the array we could do &arr[3]. So let's say that we want ptr to point to the first element of the array:

ptr = &arr[0];
Easy enough. Now with that done, let's say we want ptr to point to the second element of the array. We could do this one of two ways. We could do it just as we did above, as in:
ptr = &arr[1];
or, we could use our knowledge of pointer arithmetic to increase the value of ptr by 1, as in:
ptr += 1;
Just like every other time we've seen a pointer to an integer, we can then dereference the pointer to get at the integer's memory. So in this case, we could do *ptr to access arr[1].

So, if pointer points to the beginning of the array, as it does after executing the instruction ptr = &arr[0], then we now have two ways to access each element of the array. The first way is the one you already know, accessing the element in an array at position n, by writing arr[n]. The second method takes advantage of pointer arithmetic. We use pointer arithmetic to move us to the nth place in the array, and then dereference it to get the integer at that index. This means that arr[n] and *(ptr + n) are synonymous.

We can take this one step further. As mentioned earlier, arrays are basically pointers. In fact, the variable arr is itself a pointer (a constant one, meaning we can't change the address it points to, but nonetheless it points to something). As arr is itself a pointer, we can do pointer arithmetic on it like any other pointer, so we could access the nth element of arr using *(arr + n). This is exactly the same as doing arr[n], and the process of adding the value n to the pointer arr and then dereferencing it is most likely what is taking place behind the scenes in the computer when you use arrays.