###
They're the same!

Ok, that's not exactly true. Pointers and arrays are not
exactly the same entity, but they're very close. In fact, an
array is for all intents and purposes a constant pointer.

What?! How can an array be a pointer, and how can a pointer be
an array? Before we delve into that question, we first need to
discuss pointer arithmetic.

###
Pointer arithmetic

If you have an integer variable, you can add the number 1 to it
and the contents f that variable will increase by 1. You could
add an 'a' to a character variable and it would increase by the
value 'a'. With pointers, arithmetic is also possible, but a
little quirky. Once we understand how pointer arithmetic
works, however, it is an invaluable aid. In fact, as we'll
see, arrays work properly because of pointer arithmetic.

As we've seen, pointers store an address in memory. If we have
an integer pointer, it points to a memory location that can
hold an integer. If we have a character pointer, it points to
an address in memory that can hold a character. And so forth.
So all a pointer really holds is a big number, say, for
example, 0x4b14 (or in binary 0b0100101100010100). We might
expect that if we added a number to this, say the number 1,
that the pointer would then hold the number 0x4b15.
Fortunately, that is not always the case.

When you add numbers to pointers, the address stored in the
pointer isn't necessarily increased by that many bytes. That
would cause trouble, for example, with an integer pointer.
Let's say we had a series of integers in a row located at
addresses 0x4b14, 0x4b18, 0x4b1b, and 0x4b1f (remember that
integers on most modern machines, and the example machine we're
dealing with here, are a 4-byte data type, meaning they take up
4 bytes). Let's say that we have a pointer `ptr` that
currently holds the address 0x4b14. If we executed the
instruction: `ptr = ptr + 1;` without special arithmetic, if
`ptr` were just an integer variable, we would end up with the
value `0x4b15`. But this number doesn't make any sense in
terms of memory addresses. A single integer resides at the
memory addresses 0x4b14 through 0x4b17, so accessing the memory
at address 0x4b15 would be accessing into the middle of an
integer. Fortunately, this is not how pointer arithmetic works.

When you add a number to a pointer, the computer knows what
type of data the pointer points to, and multiplies the number
you're adding by the size of the pointer's type before adding
it to the pointer. For example, taking the case from above, if
we have the following code:

ptr = ptr + 2

and if

`ptr` is a pointer to an integer and originally
contained the value 0x4b14, then the computer really does the
math:

*ptr* = 0*x*4*b*14 + 4*2 = 0*x*4*b*1*c*
meaning that it adds 4 bytes to the pointer for every 1 unit
being added. If we were dealing with a character, normally a
one byte data structure, then the math would be:

*ptr* = 0*x*4*b*14 + 1*2 = 0*x*4*b*16
and if we were dealing with some big data structure that took
up 200 bytes for every structure, then the math would be:

*ptr* = 0*x*4*b*14 + 200*2 = 0*x*4*ca*4