はじめに
Pythonなど多くのプログラミング言語ではリスト、もしくは配列などのインデックスは0から始まります。
プログラミングを学習し始めた時からそういうものだと思って今まで来ました。
なぜインデックスは0から始まるのか?を自分なりに調べたので共有いたします。
インデックスが1から始まる言語(1-Based Indexing)
私には馴染みが無く知りませんでしたが、どうやらインデックスが1始まるプログラミング言語もあるようでした。
Lua
local fruits = {"apple", "banana", "cherry"}
print(fruits[1]) -- apple
Fortran
INTEGER :: numbers(5) = [1, 2, 3, 4, 5]
PRINT *, numbers(1) -- 1
R
numbers <- c(10, 20, 30)
print(numbers[1]) -- 10
他にもCOBOL
、matlab
、Julia
、Smalltalk
など思ったより多くの言語でインデックスが1から始まるものがありました。
これらの言語の歴史は古く、数学や統計学、科学分野で利用されていて、配列を直感的に操作できる1-Based Indexingで作られているようです。
単純に配列の2番目のインデックスは2
になるのでわかりやすいですね。
インデックスが0から始まる言語(0-Based Indexing)
どうやらC言語の登場から0-Based Indexing
が普及したようです。
C言語に影響を受けた言語では採用されています。
Python
fruits = ["apple", "banana", "cherry"]
print(fruits[1]) # banana
- C++
- C#
- Java
- PHP
- JavaScript
- Go
などなど、馴染みのある言語では大体0-Based Indexing
です。
0から始まる理由
C言語はハードウェアに比較的近い言語で、メモリを直接操作ができる言語です。配列をメモリに保存する際、配列の要素は連続したアドレスに配置され、arr[0] は配列の先頭アドレスを指します。
配列 arr[i]
にアクセスするとき、先頭アドレス + (i * 要素サイズ)
でアクセスできます。
インデックスが1から始まると 先頭アドレス + ((i - 1) * 要素サイズ)
になり若干非効率になります。
またエドガー・W・ダイクストラという方がこのように主張しています。
Why numbering should start at zero
2 ≤ i < 13
このように下限を含んで上限を含まない形式が優れていると言っています。
これは13 - 2 = 11
となり配列の長さと一致するからです。
また、0から始めると 0 ≤ i < N
とシンプルに表現できます。
こうすることでN
の数と配列の長さが一致します。
若干、そうなのか?と思う部分もあるが、
ダイクストラ氏は数学的な美しさ、プログラミングの簡潔さ、そして実践的な経験から見て、最も理にかなった選択であると主張しています。
個人的見解
直感的にわかりやすいのは1
から始める方がわかりやすいと思ったが、裏側の仕組みメモリアドレスへの保存などを考慮すると0
からのようが効率が良いから0-Based Indexing
が採用されている大きな要因なのではと感じた。
さいごに
どちらが優れているとかはないですが、それぞれの特徴や背景を知ることで少しプログラミングの知識も増えたような気がしています。