在Delphi中,为什么AnsiStrings从1开始索引,而动态数组从0开始索引?这是历史偶然还是为了使AnsiStrings更像ShortStrings,或者有其他更深层次的逻辑在起作用?
造成“Pascal”字符串从1开始索引而不是从0开始索引的其中一个原因是字符串的长度存储在零字节中。编译器可以在字符串索引表达式中内部添加常量偏移量(如Delphi的长字符串所做的那样),以使程序员看不到这一点,但在最初的阶段,事情要简单得多。分配一块内存,将长度存储在第零个字节中,从第1个字节开始索引字符数据。故事完毕。
据我回忆,UCSD Pascal早在Turbo Pascal出现之前就使用了这种零字节长度约定。
至于为什么动态数组是从零开始的,我不记得有任何具体的原因,但我猜测这反映了动态数组与动态分配缓冲区并索引缓冲区指针的亲属关系。您用于创建数组指针类型的数组类型是从零开始的数组。第一个字节位于缓冲区指针+0偏移处。这是C语言从零开始的一切的理解。当字符串的1基索引已经(并且始终)是个例而不是规范时,没有强制性的理由将字符串的1基索引模式应用到编译器管理的数组上。
很可能是因为字符串类型是每个人首次遇到的第一个类似数组的数据类型,而且可能是跨越整个领域使用最广泛的数据类型,所以可能存在对语言中向1基索引倾斜的感知。但是,如果您仔细查看,我认为您会发现Pascal中的数组(不同于字符串)从未与1基本位相关联,特别是在动态分配时。
历史的偶然性。
Pascal字符串和数组传统上从1开始。
C语言 - 也许是因为此 AnsiStrings - 从0开始。
我不知道"打破Pascal传统"在动态数组中的理由,它也从零开始。 但这很有道理,我同意...
在我看来...
mov ebx,[esp+ebx*4-$04]
,但那只是一个单一的操作码。所以无论操作看起来多么复杂,芯片都能处理它。我从未知道这一点,一直在错误的印象下劳作。感谢你让我明白了。 - David Heffernan