En realidad, creo que la versión similar a C que "comienza con 0" es muy lógica cuando se mira la forma en que se organiza la memoria. En C podemos escribir lo siguiente:
int* T = new int[10];
El primer elemento de la matriz es * T. Esto es perfectamente "lógico" porque * T es la dirección de la primera caja de memoria apuntada. El segundo elemento es el segundo caso por lo que * (T + 1): avanzamos en un "tamaño de (int)".
Para que el código sea más legible, C implementó un alias: T [i] para * (T + i). Para acceder al primer elemento, debe acceder a * T que es T [0]. Eso es perfectamente natural.
Esta idea se extiende por los iteradores:
std::vector<int> T(10);
int val = *(T.begin()+3);
T [i] es sólo un alias para * (T.begin() + i).
En fortran/R, generalmente comienza con 1 debido a problemas matemáticos, pero sin duda hay otras buenas opciones (cf this link por ejemplo). No olvide que fortran puede usar fácilmente una matriz que comience con 0:
PROGRAM ZEROARRAY
REAL T(0:9)
T(0) = 3.14
END
"Usual' 0' "es algo relativo. Mi primera taza de café por la mañana es la primera, no la cero. –
Pero cuando naces tienes cero años y tienes que esperar un año para tu primer cumpleaños. – Frank
Porque la edad se mide en * años completos *. Solo una convención diferente. Mis dedos todavía están numerados del 1 al 10. –