配列の先頭要素が「0番目」であることは気持ち悪いか…「N番目」という言葉を考察してみる
JavascriptやPHPの配列や関数などで 配列の最初の要素がary[0]に… - 人力検索はてな
C言語、Ruby、Lispなど多くの言語では配列は0起点である。つまり、先頭の要素のインデックスは0である。
なぜそうなっているか‥それは実装上の都合であったり歴史的理由だったりする。
C言語の配列は「連続したメモリ空間の、先頭アドレス」で表現している。そして、オフセットを進めることでそれぞれの要素にアクセスしている。だから配列の最初の要素を「0番目」とすることでアドレス計算が楽になるわけだ。
多くの言語はC言語の文法を拝借しているし、C言語は十分普及しているから、「C言語にあわせて配列は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起点なんだからね。
[2008/05/25]追記
class Array alias aref_org [] def [](x) aref_org(x - 1) end end
当然、これでは不十分です。 a[1, 2]やa[1..2]の場合に対応できていません。
他にも配列のインデックスを扱うArray#values_atとか、Array#indexとかもありますし。
Array#begin、Array#begin=で起点を指定できればいいのですが…
Rubyはオブジェクト指向だから $[ なんて嫌ですw
[2008/05/25]追記
404 Blog Not Found:perl - 配列を1番目からはじめてみる
$[ キターーーーーー(゜∀゜)ーーーーーー!!
Perlな人は「1からやり直しです」を「$[からやり直しです」って言うんだっけか。大昔0か1の代わりに $[ と書いてるのを見てコーヒー吹いたことがある。
[2008/05/25]追記
はてなブックマークコメントより。
これ、現実世界との接点がある説明で結構困る。「HTML上で1番目の<form>を配 列から抽出」と か。0番目の<form>ってあるの? みたいな。結局「HTMLで1番 目の<form>を配列の0要素目から 選択」とか妙な表現に
まったく…そうなんですよorz
やっぱりRubyの配列は起点を指定できると嬉しい…もちろん組み込みで。
[2008/05/25]追記
先頭要素が「1番目」であるFortran - @author pyridoxin
FORTRANやCOBOLやBASIC(可変)の配列は1起点ですね。他にはどんな言語があるのでしょう。
しかしなんでCとその子孫達は配列の要素が0からなのだろうか?Fortranは1なのに?だれか教えて?
推測ですが、C言語とFORTRANの問題領域が異なるからでしょう。C言語は機械寄りだからアドレス計算が楽な0起点になっています。
FORTRANは数値計算がメインだから1起点が無難なのでしょう。行列にしたって、左上の要素は1行目1列目の要素(A_1_1)であって0行目0列目の要素とは言わないでしょう。
*1:隠語なんだけどね…。だから正式な文書で使ってはいけないのは言うまでもない。