Delphi では、なぜ AnsiStrings は 1 からインデックス付けされ、動的配列は 0 からインデックス付けされるのですか? これは、AnsiString をより ShortString のように動作させるための歴史的な事故ですか? それとも、より深いロジックが働いているのでしょうか?
3 に答える
"Pascal" 文字列のインデックスが 0 ではなく 1 になる原因の 1 つは、文字列の長さが 0 番目のバイトに格納されていたことです。はい、これは、コンパイラが文字列インデックス式に定数オフセットを内部的に追加することによって、プログラマの視点から隠されている可能性があります(後で Delphi の長い文字列で行われたように)が、最初ははるかに単純でした。メモリのブロックを割り当て、バイト 0 に長さを格納し、バイト 1 から char データにインデックスを付けます。 話の終わり。
私が覚えているように、UCSD Pascal は、Turbo Pascal が登場するずっと前から、この長さをゼロバイトにする規則を使用していました。
動的配列がゼロベースである理由については、具体的な理由は思い出せませんが、動的配列がバッファーを動的に割り当て、バッファーポインターからインデックスを作成することとの関係を反映していると思います。配列ポインター型を作成するために使用する配列型は、ゼロ ベースの配列でした。最初のバイトは、バッファー ポインター + 0 オフセットで見つかります。これはゼロベースのすべての C 合理化です。文字列の 1 ベースのインデックス付けが標準ではなく既に (そして常に) 例外であった場合、文字列の 1 ベースのインデックス付けパターンをコンパイラ管理配列に引き継ぐ説得力のある理由はありませんでした。
文字列型は、誰もが最初に遭遇する最初の配列のようなデータ型であり、おそらく全体的に最も使用されるデータ型であるため、言語で 1 ベースのインデックス付けに偏っていると認識されている可能性があります。ただし、よく見ると、特に動的に割り当てられた場合、Pascal の配列 (文字列とは異なります) が本質的に 1 ベースではないことがわかると思います。
1 ベースの文字列という Delphi 文字列の伝統の理由は非常に単純です。伝統は、古いスタイルの Turbo Pascal 文字列の実装から来ています。そのデータ型は、文字列の長さを変数の最初のバイト (インデックス 0) に格納しました。文字列データは、次のバイト (インデックス 1) で始まりました。
現在でもそのデータ型を使用できます。現在は ShortString と呼ばれています。実装からすぐにわかるように、255 文字の制限があります。私の記憶が正しければ、この制限により、Delphi 2 で巨大な文字列が導入されました。巨大な文字列が導入されたとき、言語設計者は、開発者が短い文字列から巨大な文字列に簡単に切り替えられるように、1 から始まるインデックス付けを保持することを選択しました。
Turbo Pascal は、要素 0 を長さに使用するというアイデアを発明したわけではないと思います。若すぎてその前のことを覚えていないだけです!
動的配列は、同じように過去に縛られておらず、自由に選択できました。なぜゼロベースが選ばれたのかわかりません。おそらくそれは、当時 Delphi が存在していたプラットフォーム、つまり Windows で一般的だったファッションにより簡単に適合するためです。それはただの推測です。Danny Thorpe は当時、Delphi コンパイラに取り組んでいましたが、彼でさえその理論的根拠を思い出せません!
Delphi 言語の設計者は現在、巨大な文字列のゼロ ベースの文字列インデックス作成に取り組んでいます。この方向への最初のステップは、0 から始まるインデックスを使用する TStringHelper クラスの XE3 で見ることができます。また、ゼロベースのインデックス作成を選択できる ZEROBASEDSTRINGS 条件でも。次世代の Delphi コンパイラでは、0 ベースのインデックスのみが使用されることを期待してください。彼らが変化している時代。
歴史的な事故。
Pascal の文字列と配列は、伝統的に 1 から始まります。
C - おそらく結果として AnsiStrings - は 0 から始まります。
ゼロから始まる動的配列の「パスカルの伝統を破る」理由がわかりません。しかし、それは理にかなっており、私はそれに同意します...
私見では...