相符

相符

计算机传统上从零开始计数数值。例如,基于 C 的编程语言中的数组从索引零开始。

这其中有何历史原因?从零开始计数比从一开始计数有何实际优势?

笔记:这个问题要求回答者给出解释清楚的技术答案,而不仅仅是观点,并且旨在涵盖计算机的一般知识,而不仅仅是编程。这个问题是对程序员问题的扩展“为什么结构体/数组是从零开始的?”

答案1

从 0 开始计数数组简化了每个元素内存地址的计算。

如果数组存储在内存中的给定位置(称为地址),则可以计算每个元素的位置

element(n) = address + n * size_of_the_element

如果将第一个元素视为第一个,则计算结果变为

element(n) = address + (n-1) * size_of_the_element

差别不是很大,但每次访问都会增加不必要的减法。

编辑

  • 使用数组索引作为偏移量并非强制要求,只是习惯而已。系统可以隐藏第一个元素的偏移量,并在分配和引用元素时将其考虑在内。

  • 迪克斯特拉发表了一篇论文《为什么编号应该从零开始》(pdf) 解释了为什么从 0 开始是更好的选择。从零开始可以更好地表示范围。

答案2

虽然以下原则适用于十进制以及任何其他进制,但从计算机中使用的表示数字的固定位数二进制系统可以很容易地理解计算机中从 0 开始计数的过程。如果有 8 位,那么可以表示 1 和 0 的 256 种可能组合。您可以使用这些 8 位来表示 1-256 的数字,但这会忽略 0,0 在数学中本身就是有用的数字,因此它们用于表示 0-255 的数字。

这已经开创了从 0(二进制表示中全为 0)到 255(8 位数中全为 1)的自然顺序的先例。考虑到表示数字的系统,从 0 开始是有意义的,因为 0 是系统中的“第一个”数字,所以 1 是“第二个”数字,依此类推。

在计算机中从 0 开始非常方便的另一个原因是偏移量的概念。偏移量是一个数字,表示与内存或硬盘或任何其他“可寻址”介质中某个位置的距离。在计算机中,几乎所有数据都是线性存储的,这意味着数据有顺序,第一个字节,第二个字节等。通过偏移量来表达数据“区域”的位置很方便。数据块中的第一个字节是什么?它位于偏移量“0”处,这意味着它位于数据块中第一个字节之后的 0 个字节处。虽然可以用“1”表示第一个字节,但这会造成数据表示的复杂性,原因如下:

  • 通过排除使用 0 来寻址数据,您可以将使用 8 位数寻址的对象数量减少 1。
  • 为了计算偏移量(这在数据访问的硬件级别是必需的),在某些时候您必须从编号中减一,这会带来复杂性。
  • 指向数据块的指针始终指向第一个块,因此从 0 开始时算术很简单。(即,从 0 开始时,第一个数据簇的第一个块中的第一个字节是 0 + 0 + 0,从 1 开始时,它是 1 + 1 + 1 - 1 -1。)当从 1 开始时,使用类似本例的嵌套数据结构进行算术运算可能会令人困惑。

答案3

从来没有想过像我这样的空谈哲学家会在 Superuser 上得到这样的机会。这里存在一个根本性的误解,因为非哲学家往往会忽略细节。简而言之: 计算机不是从零开始计数,但是位置的面值从零开始。

计算机和人类(任何)计数技术之间这种明显的不一致并不令人困惑。让我们分解一下这个问题。

为什么计算机从零开始计数?

  • 它们不是从零开始计数的

计算机从零开始计数值。例如,C 语言中的数组。

  • 指数(位置指示器,计数)从零开始。数数数组中索引为零处只有一个元素的元素数为

零是用来表示某种东西的空白或一个尺度的中间点的。它不适用于数数任何事情,因为根据零的定义这是不可能的。

零点与标尺的中间点意义相同,可用于表示集合的最边缘(绝对起点)。这个问题毫无意义,因为“计数值”和“从零开始计数”不一致。

所以是的,计算机确实是从零开始计数,但它们是从一开始计数。这两个词的含义不同。

相符[tal-ee]

名词

  1. 帐户或清算;借方和贷方的记录、游戏得分的记录或类似记录。
  2. 任何记分或记账的事物。
  3. 记录的数目或一组项目。

数数[折扣]

动词(与宾语连用)

  1. 逐一检查(集合中的独立单元或组)以确定总数;加起来;列举:他数了一下票,发现有十张。
  2. 计算;估算;估量。
  3. 列出或说出数字:闭上眼睛,数到十。

(dictionary.com)


Dougvj 已经充分描述了实际原因,我没什么可补充的了。如果我们能有一位计算机科学教授(来自 60 年代)来讲述历史就好了……

答案4

其他人提出的距离类比可以作为非常实际的例证:

“你家离最近的加油站有多远?”

“1英里。”

“你住在加油站吗?”

“不,如果我住在加油站附近,那就没有里程了”

“为什么从零开始数,而不是从一开始呢?”

另一个很好的例子就是生日——我们不会说某人出生那天一岁,而是说一年后。

我们说闰年或美国总统选举每四年一次,尽管如果你从一开始数:2000,2001,2002,2003,2004是五年。(顺便说一句,罗马人确实搞砸了一段时间,闰年间隔得太近了)

我的观点是,在现实世界中,我们总是从零开始“计数”——“你想要的元素在[数组开头]之后的多少个位置”恰好是你在许多计算机程序中用从零开始计数来回答的问题。你不会说第一个元素是一个位置开始,你会吗?开始。

相关内容