Actually, I think that the C like version that "start with 0" is very logical when you look at the way the memory is organized.
In C we can write the following :
int* T = new int[10];
The first element of the array is *T. This is perfectly "logical" because *T is the adress of the first memory case pointed. The second element is the second case so *(T+1) : we move forward by one "sizeof(int)".
To make the code more readable, C implemented an alias : T[i] for *(T+i).
To access the first element, you have to access *T that is T[0]. That's perfectly natural.
This idea is extended by iterators :
std::vector<int> T(10);
int val = *(T.begin()+3);
T[i] is just an alias for *(T.begin()+i).
In fortran/R, we usually start with 1 because of mathematical issues but there's certainly other good choices (cf this link for example).
Do not forget that fortran can easily use array that start with 0 :
PROGRAM ZEROARRAY
REAL T(0:9)
T(0) = 3.14
END