共计 758 个字符,预计需要花费 2 分钟才能阅读完成。
原文地址: 为什么数组下总是从 0 开始呢?
这个问题有没有想过?会不会认为为何设计的如此反人类呢?
有两种比较好的说法,我们了解下:
说法一
表示范围的最佳形式,比如表示自然数序列 2,3,···,12,有四种方法:
a. 2 ≤ i < 13
,或者记作 [2, 13)
。
b. 1 < i ≤ 12
,或者记作 (1, 12]
。
c. 2 ≤ i ≤ 12
,或者记作 [2, 12]
。
d. 1 < i < 13
,或者记作 (1, 13)
。
a 方法是最好的,有如下原因:
- 范围的上限减去下限等于范围内元素的个数
比如方法 a 中,13 – 2 = 11,而范围内刚好就有 11 个元素,方法也有同样的性质,但方法 c 和 d 就没有。
- 连续的范围没有重叠
两个连续的范围我们希望可以写成“0 到 5”和“5 到 9”这样的形式。如果使用方法 c,12 就同时包含在 [2, 12] 和 [12, 24] 这两个范围里;类似的,使用方法 d,13 既不包含在 (2, 13) 里也不在 (13, 25) 里。用方法 a,b 就没有这样的问题。比如 [2, 13) 和 [13, 25) 是两个连续的范围,13 只会包含在后一个里。
方法 a 比方法 b 好的理由:我们常常会用到有下限无上限的集合,最典型的是自然数集合。比如要表示自然数集合内的范围“0 到 10”,用方法 a 可以写成 [0, 11),用方法 2 可以写成 (-1, 10]。方法 b 的问题是形式中出现了 – 1 这个非自然数,用非自然数来表示一个自然数集合内的范围显然不是一个好的选择。
说法二
我们常说的数组下标最精确的意思是”偏移量“,a[0] 的偏移量是 0,即为首地址。a[i] 的偏移量是 i,寻址公式:
a[i] 地址 = 首地址 + i * 数据大小
如果下标从 1 开始,那对应的寻址公式
a[i] 地址 = 首地址 + (i-1) * 数据大小
对 CPU 来说,每次随机访问,就多了一次减法运算,多发一条指令,所以从 0 开始可以减少 CPU 的计算。
想了解很多,请关注下面: