This was actually written in the book I used to learn C (I think, at least I knew this early on). It seems completely irrational when someone tells you that ptr[3] == 3[ptr], but with the above explination it makes perfect sence.
BCPL C
!a *a
a ! 0 a[0]
0 ! a 0[a]
!(a + 0) *(a + 0)
!(0 + a) *(0 + a)
That’s where C got its 0-based semantics from—it would be a nasty surprise if 0 weren’t the identity for pointer addition!