EWD831 为什么编号应该从零开始

为了表示自然数子序列 2, 3, ..., 12,并且避免使用令人厌恶的省略号,我们有四种约定:

a) | 2 ≤ i < 13 ---|--- b) | 1 < i ≤ 12 c) | 2 ≤ i ≤ 12 d) | 1 < i < 13

有没有理由偏爱其中一种约定? 是的,有。 约定 a) 和 b) 的优点在于,显式给出的边界之差等于子序列的长度,这个观察是有效的。 同样,由此可见,在任一约定中,两个子序列相邻意味着一个子序列的上界等于另一个子序列的下界。 尽管这些观察结果有效,但它们并不能使我们在 a) 和 b) 之间做出选择; 因此,让我们重新开始。

存在一个最小的自然数。排除下界(如 b) 和 d) 中所示)迫使从最小自然数开始的子序列的下界进入非自然数的领域。 这是令人不快的,所以对于下界,我们更喜欢 a) 和 c) 中的 ≤。 现在考虑从最小自然数开始的子序列:包含上界将迫使后者在序列缩小为空序列时变为非自然数。 这是令人不快的,所以对于上界,我们更喜欢 a) 和 d) 中的 <。 我们的结论是,约定 a) 应该被优先选择。

备注 在 Xerox PARC 开发的编程语言 Mesa 具有用于所有四种约定的整数区间的特殊表示法。 Mesa 的丰富经验表明,使用其他三种约定一直是笨拙和错误的根源,并且根据该经验,现在强烈建议 Mesa 程序员不要使用后三种可用功能。 我提到这个实验证据——无论其价值如何——因为有些人对未经实践证实的结论感到不舒服。(备注结束)


在处理长度为 N 的序列时,我们希望通过下标来区分序列的元素,下一个令人烦恼的问题是为它的起始元素分配什么下标值。 坚持约定 a),当从下标 1 开始时,会产生下标范围 1 ≤ i < N +1; 然而,从 0 开始会产生更漂亮的范围 0 ≤ i < N。 所以让我们从零开始编号:一个元素的序号(下标)等于序列中它前面的元素个数。 这个故事的寓意是,经过这么多个世纪之后,我们最好将零视为最自然的数字。

备注 许多编程语言的设计没有充分注意这个细节。 在 FORTRAN 中,下标始终从 1 开始; 在 ALGOL 60 和 PASCAL 中,采用了约定 c); 较新的 SASL 已经退回到 FORTRAN 约定:SASL 中的序列同时也是正整数上的函数。 真可惜!(备注结束)


以上是由最近发生的一件事引发的,当时,我的一位数学同事——不是计算机科学家——在情绪爆发中指责一些年轻的计算机科学家“迂腐”,因为——就像他们习惯的那样——他们从零开始编号。 他认为有意识地采用最明智的约定是一种挑衅。(“End of …”约定也被视为具有挑衅性;但该约定很有用:我知道一位学生几乎在考试中不及格,因为他默认问题在第一页的底部结束。) 我认为 Antony Jay 说的是对的:“在公司宗教中,就像在其他宗教中一样,异端必须被驱逐,不是因为他很可能犯错,而是因为他有可能是对的。”

Plataanstraat 5 5671 AL NUENEN The Netherlands | 1982 年 8 月 11 日 prof.dr. Edsger W. Dijkstra Burroughs Research Fellow ---|--- 转录者: Kevin Hely。 最后修订于 2008 年 5 月 2 日星期五。