JavascriptやPHPの配列や関数などで 配列の最初の要素がary[0]に… - 人力検索はてな

Ｃ言語、Ruby、Lispなど多くの言語では配列は0起点である。つまり、先頭の要素のインデックスは0である。

なぜそうなっているか‥それは実装上の都合であったり歴史的理由だったりする。

Ｃ言語の配列は「連続したメモリ空間の、先頭アドレス」で表現している。そして、オフセットを進めることでそれぞれの要素にアクセスしている。だから配列の最初の要素を「0番目」とすることでアドレス計算が楽になるわけだ。

多くの言語はＣ言語の文法を拝借しているし、Ｃ言語は十分普及しているから、「Ｃ言語にあわせて配列は0起点でいいや」となっていると推測している。コンピュータの世界じゃ歴史的理由ってのがけっこう多い。

そういうわけでプログラマが配列の要素を数えるとき、勝手に「0番目」→「1番目」→「2番目」と数えている。新しい言語でも0起点とするのは、プログラマにとって自然だ。

しかし、日本語の観点では「0番目」というのはいささか気持ち悪い。「日本語」では、順番に並んでいるものの先頭は「1番目」として数えるからだ。

気持ち悪いのは確かなんだが、こうは考えられないか？「N番目」という言葉は、プログラミングの文脈では「インデックスがN番目」という意味にオーバーライドされていると考えるのだ！言葉なんて文脈によって意味が異なるじゃん。「鯖」という言葉をとってみても、一般的な意味では魚のサバだが、インターネットの文脈ではserverを意味する*1。

それでもいささか気持ち悪いのは、（0起点の）「N番目」という言葉は、通常の日本語の意味の（1起点の）「N番目」という言葉で表現できてしまうからだろう。Rubyなどのオブジェクト指向プログラミング言語でいえば「super」だ。

この「N番目」という言葉はかなりの曲者で、プログラミングの解説の文脈でも0起点だったり、1起点だったりするのだ！

たとえば解説でインデックスが「+1」されていれば普通の日本語の「N番目」という意味だ。

ary = [:foo, :bar, :baz] ary.each_index do |i| puts "#{i+1}番目の要素は#{ary[i].inspect}です。" end # >> 1番目の要素は:fooです。 # >> 2番目の要素は:barです。 # >> 3番目の要素は:bazです。

一方、Array#［］の解説では「N番目の要素を得る」と書いてある。これは0起点の「N番目」が使われている。Array#［］の解説で「N+1番目の要素を得る」と書かれているのはほとんど見かけない。これは…理解のしやすさ、文章のすっきり度なんだろうね。

こんな感じでプログラミング解説で「N番目」という言葉が出てきたら、プログラマは脳内で無意識に「0起点かな、1起点かな」と考えさせられる。脳味噌のCPUタイムの無駄である（笑）それでも、経験的にプログラミング解説では0起点の「N番目」が使われていることが多いようだ。

どうしても気持ち悪いのが抜けないならば、いっそのこと新しい表現を使えばいいじゃないか。（0から数えて）「N番目の要素」という表現を「インデックスがNの要素」と言い換えてみる。それなら間違いなく0起点なんだからね。