为什么写这篇文章?
实际上这个问题已经被讨论烂了,网上各种精彩的回答数不胜数,可就在我去查阅的时候,发现真的是个递归屎山。本回答会淹没在茫茫的文章中,写下这个,仅仅是为了做个笔记罢了。
前言
我们熟悉的Java, C, C++, Python都是用0开始的,网上有些答案也说得很直白,彷佛从0开始就是个很正常的现象,问这个问题的人不是小白就是弱智。可是我们举反例就行了,Matlab的数组下标是从1开始的,这个例子就证明了从0或者从1开始,都不是绝对的好,不然为什么有一些语言使用1开始呢?
事实上,从0或者从1开始,经历了漫长的争论,本质上就是一个问题:从1开始符合人类习惯,从0开始符合计算机习惯,我们究竟选择哪个呢?
正文
我们知道硬件的下标是从0开始的,如果从1开始,就浪费了10分之一的硬件资源,这在早期的计算机世界中,昂贵的硬件价格,舍弃硬件资源是不可想象的。这也是有一些答主说的:和C语言中指针取值有关。可是为什么后面的语言仍然用0开始,答主们很简单的说:因为前辈们就是这么用的,所以也要这么用。显然这个说法不能让人信服。
今天主要介绍两位大佬:Edsger W. Dijkstra 和 Guido van Rossum。前者是《数据结构》教科书上大名鼎鼎的大佬,后者是Python之父。
Edsger W. Dijkstra
大佬的于1982年写的一个备忘录,可以解释他的理由,在此我言简意赅的总结下。
如果我们要表示2,3,4,5,6该选择什么样的方式呢?
a) 2 ≤ i < 7
b) 1 < i ≤ 6
c) 2 ≤ i ≤ 6
d) 1 < i < 7
- 首先,c和d被排除,因为这个队列中有5个数,c和d中两端相减,一个等于4,一个等于6,不能立即得出有5个数。而a和b能直接得出5.
- 如果选b的话,那么起始的将会是一个非自然数,这样不够优雅。选用a。起始的值是2,这是一个自然数。
- 综上所述,大佬投票支持a。
- 开始下标为 1 的时候,下标的范围是 1 ≤ i < N+1。然而,从 0 开始的话,可以得到更好的范围 0 ≤ i < N,这不仅看起来更美丽,而且还遵循了数学中0作为最自然数字的传统。
- 易得,大佬投票支持左闭右开,且从0开始的方式。
Guido van Rossum
这位大佬在社区上回复了网友的提问,在此我言简意赅的总结下。
- 大佬承认了很多语言是从1开始的,并且为之也纠结过。
- 最终选择0开始的,很大程度上是因为列表的切片。
- 使用0-based的索引方式,Python的半开区间切片和缺省匹配区间切片语法变得非常漂亮: a[:n] 和 a[i:i+n],前者的标准写法就是a[0:n]。
- 而如果是1-based的方式,半开区间切片非常不优雅。
- 而如果是1-based的方式,且是闭合区间,那么为了表达从第i位取n个元素时,你必须写出a[i:i+n-1],这样子看来,切片起始位+长度的形式更合适,你可以写成a[i:n]。事实上ABC语言就是这样做的。
- 从0开始且是半开区间的切片方式太漂亮了。例如,你想将一个数组以i,j两个点切成三部分——这三部分将会是a[:i],a[i:j]和a[j:]。
- 显而易见,大佬投票支持左闭右开,且从0开始的方式。
结论
- 略