7

在 Delphi 中,为什么 AnsiStrings 从 1 开始索引,而动态数组从 0 开始索引?这是一个历史性的意外,让 AnsiStrings 更像 ShortStrings 工作,还是有一些更深层次的逻辑在起作用?

4

3 回答 3

12

导致“Pascal”字符串被 1 索引而不是 0 索引的促成因素之一是字符串的长度存储在第零字节中。是的,这可以通过让编译器在内部向字符串索引表达式添加一个常量偏移量来隐藏在程序员的视野中(就像稍后在 Delphi 的长字符串中所做的那样),但一开始事情要简单得多。分配一块内存,将长度存储在字节 0 中,从字节 1 开始索引 char 数据。故事结束。

我记得 UCSD Pascal 早在 Turbo Pascal 出现之前就使用了这种长度为零字节的约定。

至于为什么动态数组是从零开始的,我不记得有任何具体原因,但我猜它反映了动态数组与动态分配缓冲区和索引缓冲区指针的关系。您将用于创建数组指针类型的数组类型是从零开始的数组。第一个字节位于缓冲区指针 + 0 偏移处。这是基于零的一切的 C 合理化。当字符串的基于 1 的索引已经(并且一直是)例外而不是规范时,没有令人信服的理由将字符串的基于 1 的索引模式转移到编译器管理的数组中。

很可能是因为字符串类型是每个人第一次遇到的第一个类似数组的数据类型,并且可能是全面使用最多的数据类型,因此可能存在一种偏向于语言中基于 1 的索引的看法。但是,如果您仔细观察,我认为您会发现 Pascal 中的数组(与字符串不同)从来没有本质上是基于 1 的,尤其是在动态分配时。

于 2012-10-30T08:18:18.677 回答
4

Delphi 字符串传统基于 1 的字符串的原因很简单。传统来自旧式 Turbo Pascal 字符串的实现。该数据类型将字符串的长度存储在变量的第一个字节索引 0 中。字符串数据从下一个字节索引 1 开始。

您今天仍然可以使用该数据类型。它现在称为 ShortString。从它的实现中可以立即看出,有 255 个字符的限制。如果我没记错的话,这个限制导致在 Delphi 2 中引入了大字符串。当引入大字符串时,语言设计者选择保留基于 1 的索引,以便开发人员更容易从短字符串切换到大字符串。

我猜 Turbo Pascal 并没有发明使用元素 0 作为长度的想法。只是我太年轻了,不记得之前发生了什么!

动态数组不会以同样的方式受过去的束缚,并且可以自由选择。我不知道为什么选择基于零。也许是因为它更容易适应当时 Delphi 存在的平台上的流行时尚,即 Windows。这只是一个猜测。Danny Thorpe 当时从事 Delphi 编译器的工作,连他都不记得其中的原理了

Delphi 语言设计者目前正朝着大字符串的基于零的字符串索引方向发展。可以在 XE3 中的 TStringHelper 类中看到这个方向的初始步骤,该类使用基于 0 的索引。并且还在 ZEROBASEDSTRINGS 条件中,它允许您选择基于 0 的索引。期望下一代 Delphi 编译器仅使用基于 0 的索引。他们正在改变的时代。

于 2012-10-30T08:17:12.280 回答
0

历史事故。

Pascal 字符串和数组传统上从 1 开始。

C - 可能是 AnsiStrings - 从 0 开始。

我不知道动态数组“打破帕斯卡传统”的理由,动态数组也从零开始。但这是有道理的,我同意它......

恕我直言...

于 2012-10-30T05:20:23.303 回答