It's fairly straightforward if you're a C programmer and think of arrays as contiguous blocks of memory.
int * a = (int * )malloc(5);
a is a pointer to the beginning of an integer (default 4 byte) array. a[i] == a + i == ((uint8_t * )a)+i*sizeof(int). Therefore, a[0] == a + 0 == the first element in a contiguous block of memory.
If that blows your mind, you might want to avoid looking at the following: "foo"[2] == ("foo"+2) == (2+"foo") == 2["foo"]. And yes, you really can do that: in general a[b] and b[a] are exactly the same thing in C.
oh, bother, I forgot what HN does to asterisks. In what I wrote above, look for the bit in italics and mentally insert asterisks on each side of it. It was right when I typed it in, I promise...
int * a = (int * )malloc(5);
a is a pointer to the beginning of an integer (default 4 byte) array. a[i] == a + i == ((uint8_t * )a)+i*sizeof(int). Therefore, a[0] == a + 0 == the first element in a contiguous block of memory.