この質問には少し遅れていますが、これは理由に答えようとします-質問の部分:
その理由の 1 つは、メモリのアドレス指定時にゼロベースのインデックス作成/オフセットを使用しているためです。
最も簡単な例は配列です。「6 項目の配列」は、6 つのデータ項目を格納する場所と考えてください。この配列の開始位置がメモリ アドレス 100 にある場合、データ (たとえば 6 文字の「apple\0」) は次のように格納されます。
memory/
array contains
location data
100 -> 'a'
101 -> 'p'
102 -> 'p'
103 -> 'l'
104 -> 'e'
105 -> '\0'
したがって、6 項目の場合、インデックスは 100 から 105 になります。アドレスはbase + offsetを使用して生成されるため、最初の項目はベース メモリ位置100 +オフセット0 (つまり、100 + 0) にあり、2 番目は 100 + 1 にあり、3 番目は100 + 2、...、100 + 5 が最後の位置になるまで。
for
これが、ゼロベースのインデックスを使用する主な理由であり、C のループなどの言語構造につながります。
for (int i = 0; i < LIMIT; i++)
またはPythonで:
for i in range(LIMIT):
ポインターをより直接的に扱う C のような言語でプログラミングする場合、またはアセンブリーをより直接的に扱う場合、この base+offset スキームはより明白になります。
上記の理由により、多くの言語構造は自動的にstartからlength-1までの範囲を使用します。
ウィキペディアのゼロベースの番号付けに関するこの記事と、Software Engineering SE からのこの質問も興味深いかもしれません。
例:
たとえばCでは、配列があり、配列の(ベース)アドレスを取得してそれに追加することと実際に同等であるため、ar
添字を付ける場合=>これにより、配列の内容を出力するこのようなコードが簡単に表示されますベース + オフセット アプローチ:ar[3]
ar
3
*(ar+3)
for(i = 0; i < 5; i++)
printf("%c\n", *(ar + i));
本当に同等
for(i = 0; i < 5; i++)
printf("%c\n", ar[i]);