All good answers. A good part of my "career" was spent in Fortran, where all arrays are 1-based. It's OK if you're writing math algorithms over vectors and matrices, where indices naturally go 1 .. N.
But as soon as you start trying to do computer-science type algorithms, where you have a big array and you are working on pieces of it, as in binary search, or heap sort, or if it is a memory array and you are writing memory allocation and freeing algorithms, or starting to act like parts of it are actually multidimensional arrays that you have to calculate indices in, that 1-based stuff gets to be a real source of confusion.
For example, if you have a 1-dimensional array A, and you want to treat it as a 2-dimensional NxM array, where I and J are the index variables, in C you just say:
A[ I + N*J ]
but in Fortran you say
A( (I-1) + N*(J-1) + 1 )
A( I + N*(J-1) )
If it was 3-dimensional, you had to do
A( I + N*(J-1) + N*M*(K-1) )
(That's if it was column-major order, as opposed to row-major order which is more common in C.)
What I learned to do in Fortran, when doing string manipulation algorithms, was never to think of an index I as being the position of an element in an array.
Rather I would think of a "distance" N as being the number of elements coming before the element of interest.
In other words, always think in terms of "number of elements" rather that "index of element". That enabled me to work within what was an unnatural indexing scheme.