何故配列のインデックスが0から始まるのか

「何故配列の添字は0から始まるのか」を理解する方法 (Kanasansoft Web Lab.)より。

これって、C言語を知っていれば簡単に説明ができます。

int a[5];

と、配列を宣言した際、intのサイズのメモリが5個確保され、aにはその配列の先頭アドレスが入ります参照:配列とポインタ変数には何の関係も無いよ
配列のインデックスというのは何番目の要素を指すというより、この先頭アドレスからどれだけずれた位置のアドレスから値を取ってこいという命令です。

配列の先頭の場合は、配列の先頭アドレスと一致するので、ずらし量は0です。なので、

a[0] = *(a + sizeof(int)*0)

となります(Cの書き方としては、若干違うんだけど、イメージしやすさとして)。

同様に、先頭から2番目の要素は、配列の先頭アドレスから型のサイズ1つ分ずれている位置に存在するので、

/* 
 * C としては、ポインタの足し算すると型のサイズ分ずらしてしまうから
 * 下の書き方では、期待する動きをしません。キャストがあるとわかりづらいから、
 * はぶいています。
 */
a[1] = *(a + sizeof(int)*1) 

となるわけです。

ためしに、以下のようなコードを書いて実行してみます。

#include <stdio.h>

int main()
{
    int a[5] = {1,2,3,4,5};
    int *b = (int*)((int)a+sizeof(int)*2);
    
    printf("a[2] = %d\n",a[2]);
    printf("a + 2 = %d\n",*(a+2));
    printf("(int*)((int)a+sizeof(int)*2) = %d\n",*b );
    return 0;
}
$ gcc -o index index.c
$ ./index 
a[2] = 3
a + 2 = 3
(int*)((int)a+sizeof(int)*2) = 3

というわけで、僕の配列の添え字が何故0から始まるかという考え方。間違っているとか、こういう考え方もあるぉとかのツッコミがあればお願いします。(どこかで、こうだっていうのを見たんだけど思い出せないんだよなぁ。Write Great Codeの第一巻かと思って調べようと思ったら、まだ段ボールの中だ。今、プログラミング言語の概念と構造を調べたら、169ページに似たようなことがのっていた。)