Z punktu widzenia C i C++, powód jest prosty:
Dzięki temu przy operacjach na wskaźnikach A[B] może w sposób naturalny być analogiczne do *(A+B). Wskaźnik na tablicę A jest jednocześnie wskaźnikiem na pierwszy element, więc A[0] == *(A+0) == *A. Gdyby pierwszym elementem był A[1], trzeba by to było nieintuicyjnie konwertować na *(A+B-1).
A historycznie...
Język C został stworzony w USA a jego 'potomek' jest język C++.
Wiesz co, nie wszystko zaczęło się od C. Pierwszym językiem z indeksowaniem od zera (wtedy jeszcze nie było nawet idei tablic) był BCPL (stworzony w UK :P). Poza tym, że, jak pokazałem powyżej, ma to więcej sensu (co potem jeszcze dokładniej uzasadnił Dijkstra w swoim tekście "Why numbering should start at zero"), to oszczędzało to parę cykli, które w tamtych czasach były znacznie cenniejsze.
Lektura: http://exple.tive.org/blarg/2013/10/22/citation-needed/