起源

计算机编程中列举数据从零开始编号,主要起因于提供的机器指令,根据条件判断,程式要能在指令序列之间“跳转”,这是实作分支结构的关键。可用条件以判断暂存器内容的“零”和“负”为主。最常用于实作迭代的指令譬如“递减,如果到零就跳转”。也就是说,任何可列举的数据结构都在迭代中循环处理,而是否为零的条件判断,用于控制这些循环的执行(不为零就一直在循环中)。高阶编程语言的循环结构(如do-while,repeat-until,for-step-to...)是基于这些根本的机器指令。

BCPL编程语言(C编程语言的前身)的创建者,马丁·理察德(Martin Richards)设计了阵列从0开始的索引方式,作为存取阵列开头内容的自然位置,因为表示位址的指针p值,用于存取内存中的p+0位址;系统分析师Mike Hoye询问Richards选用该惯例的原因。BCPL最初是用IBM 7094机器编译的;它在编译时会优化这些阵列索引提供的指针反参考运算(indirection)。

在1982年艾兹赫尔·戴克斯特拉(Edsger Wybe Dijkstra)写了个相关的说明《为什么编号应该从零开始》,将阵列索引的上下界以不等式连接,来分析各种设计方案,列举出严格和标准不等式的四种可能组合,展示了他的确信,从零开始编号的阵列不会造成索引范围重叠,是最好的表示方法,从零开始暗示与实数同样的开,半开和闭区间。偏好这惯例的细节以空序列说明,它可以用更自然的(a≤i

编程语言用法

这种设计方案嵌入在许多具影响力的编程语言中,包括C,Java和Lisp。在这三种语言中,序列类型(C阵列,Java阵列和串列,Lisp串列和向量)以数字零为下标开始索引。特别是在C语言中,阵列与指针运算紧密相关,这使得一个更简单的实现:下标的参考是从阵列起始位置的偏移,因此第一个元素的偏移量就是零。

几乎所有计算机结构,都借由位址和偏移量来表示直接引用内存,因此C语法的设计细节使编译更容易,但代价是一些人工成本。这样的情况下,使用“第零”作为序数并不是严明正确的,而是计算机业界的普遍惯例。其他编程语言如Fortran或COBOL,则有从一开始的阵列索引下标,因为它们意味着高阶编程语言,因此它们必须与通常的序数相对应。一些最近的编程语言如Lua,由于同样原因采用了相同的约定。

零是最低位的无符号整数值,是编程和硬件设计中最基本的类型之一。因此在计算机科学,零经常被当作许多种类的数值递归的基本情况。计算机科学中的证明和其他类型的数学推理通常从零这一数开始。由于这些原因,在计算机科学中,从零而非从一开始计数的方式并不少见,时有用例。

黑客和计算机科学家经常喜欢将出版品的第一章,如果其内容特重于介绍的概念,则称为“第0章”。其中一个经典的例子是在K&R的第一版。近年来在许多纯数学家中也出现这种特征,许多构造被定义为从0开始编号。

如果用阵列表示循环,则模除(modulo)函式即可便利地获得索引,而这会导致零。

数值属性

使用从零开始的编号范围表示为半开区间

[

0

,

n

)

{\displaystyle [0,n)}

,不同于闭合区间

[

1

,

n

]

{\displaystyle [1,n]}

。在算法中经常发生的“空”范围,很难以闭合区间[1,0]来表达。由于这个属性,从零开始的索引潜在地减少了差一和栅栏错误。但另一方面,预先扣除掉重复的计数

n

{\displaystyle n}

,使得从

0

{\displaystyle 0}

n

1

{\displaystyle n-1}

(包含)的表达较不直觉。有些作者更偏好从

1

{\displaystyle 1}

开始的索引,因为它直接对应了该项目在其它段落中的索引。

零索引惯例的另一个特性是在现代计算机中实作的模运算。通常,模函数将任何模

N

{\displaystyle N}

映射到

0

,

1

,

2

,

,

N

1

{\displaystyle 0,1,2,\dots ,N-1}

中的一个数字,其中

N

1

{\displaystyle N\geq 1}

。因此在算法(例如计算杂凑表索引)中的许多公式,当序列从零开始索引时,使用模运算可优雅地以代码表示。如上文所提及位址/偏移量的底层逻辑,指针操作也能以零索引更优雅地表示。

为了说明,假设

a

{\displaystyle a}

是阵列中第一个元素的内存地址,

i

{\displaystyle i}

是需求元素的索引。要求所需元素的位址,如果从

1

{\displaystyle 1}

开始计算索引号,则通过以下表式计算:

a

+

s

×

(

i

1

)

{\displaystyle a+s\times (i-1)}

,其中

s

{\displaystyle s}

是每个元素的大小。若从0开始计数,则表达式变为:

a

+

s

×

i

{\displaystyle a+s\times i}

,这个简单的算式可在执行时期更有效率地计算。

然而注意,从1开始索引阵列的语法也能从简采用约定:每个“阵列位址”以

a

=

a

s

{\displaystyle a'=a-s}

来表示;

也就是说,不采用阵列中第一个元素的位址,这种语法使用某个“虚拟”元素的位址,紧接在实际的第一个元素之前。从1开始索引的表式如下:

a

+

s

×

i

{\displaystyle a'+s\times i}

因此零索引的执行期效率来自以0暂代第一元素的实际位址,不使用阵列之前的“虚拟”元素位址,此设计策略的优势。可是,直接位于阵列之前的“虚拟”元素位址,或许是与阵列无关的其他项目,能有作用的位址。这种情况可能导致术语上的混乱。

在零索引方案中第1个元素是“下标零”;同理第12个元素是“下标11”。所以从序数到物件数量的转换浮现;n个元素的最高索引会是n−1并且被称为第n元素(表示数量为n,上界索引与计数差一)。反之第一个元素就被称为第零物件(直接以序号指称),以避免混淆。

Copyright © 2088 俄罗斯世界杯主题曲_世界杯下一届 - pin8pin8.com All Rights Reserved.
友情链接