为了记数方便

注意这个红色的0,这里是从零开始。
内存地址是从0开始,如果内存上装载一个数据如int类型。
一个int类型是4个字节,那么假设一个int的 data_type_size=4。
那么数据的内存是连续的,那初始化5个数组就是:
int[] a = new int[5],到这都很清楚吧。

base_address = 1000

那么假设首地址从1000开始,连边开5个内存地址就是:int[5]
公式

a[i]_address = base_address + i * data_type_size

那么来推一下:
下标:i=0 数组[0]:

a[0]_address = base_address + 0 * data_type_size

下标:i=1 数组[1]:

a[1]_address = base_address + 1 * data_type_size

最络结果是这样

i=0 { a[0] } 1000-1003
i=1 { a[1] } 1004-1007
i=2 { a[2] } 1008-1011
i=3 { a[3] } 1012-1016
i=4 { a[4] } 1016-1020

这有啥,不就是常规操作嘛,下面换个角度看。

减少CPU指令运算

如果下标从1开始,base_address 这种内存地址还是从 1000 开始
下标:i=1 数组[1]:

a[i]_address = base_address + (i-1) * data_type_size

那就是

a[1]_address = 1000 + (i-1) * 4

有什么不一样吗?
不一样的地方就是多了一步i-1 的操作,-1 这个操作需要CPU额外多计算一次,这不就是费了一丝性能嘛。
在那个登月火箭的计算性能只有一个电子表的时代理,这一丢丢的性能损耗放大到一个工程里可是不小的损耗。
而且做为系统级别的设计,更是需要把性能压榨到最优。