一些流行的编程语言使用减去 1 的月份编号——我想到的是 JavaScript,Java 也是如此,如果没记错的话,C 也是如此。我有一些问题:
使用零开始计数实际上是汇编程序员的一个优化技巧。他们没有将 1 分配给计数寄存器,而是将寄存器与其自身进行异或运算,这在 CPU 周期中稍微快一些。这意味着计数将从 0 开始,并且始终达到元素的长度(不包括最后一个元素)。
此外,零的使用在指针算术中也很流行,您可以使用一个指向某个已分配内存的基指针,加上第二个指针,该指针位于距该基指针的偏移量处。在这里,使用值零将偏移量指向内存块的基址非常有意义。 (一般数组逻辑往往是基地址加上偏移量 x 记录大小。)
还有从零开始的月份数字?通常,许多编程环境将数据计算为自某些默认数据以来的天数。 1899 年 12 月 31 日是一个很受欢迎的日期,尽管还有很多其他日期用作基准日期。所有其他日期都从该基数偏移,并且仅存储为一个数字。分数将用于表示小时、分钟和秒,其中 0.25 表示 24/4 = 6 小时。因此,要将日期转换为真实日期,环境所要做的就是将此数字转换为真实日期。
但是,从零开始的数组和从1开始的月份值的组合确实带来了问题。 要获取 9 月的月份名称,您必须从月份数组中获取第 8 项。一些开发人员会很乐意在获得名称之前减少月份数字。其他人更喜欢将月份更改为从零开始的内容,因为人们只想知道名称,而不是数字。以上纯属个人观点。
事实就是如此,根据该假设构建的软件的巨大重量意味着它会存在一段时间。
我的意见是这是C的错误,所有其他后来出现的语言都与它一致。
你会从不太了解的人那里得到一些有趣的情况。我们团队发现的少数几个千年虫错误之一是一个网站自豪地宣称年份是 19100 年,只是因为他们在
struct tm
年前面加上了文字“19”。
是的,罗马人也有零的问题。
这只是数学(是编程的重要组成部分,尤其是早期编程)的[非直观]结果,将零定义为第一个(有问题的术语)实数,正*自然数,并且因为数组使用实数、自然数进行索引,“第一个”元素位于索引 0 处。
月份实际上是数组中的命名值,其中天和年是编号值 - 将天/年视为位于看起来像 { "1", "2", "3", ... } 他们自己。
至于为什么这种情况如此常见(除了数学上正确之外),那么您列出的所有语言都源于同一事物的共同起源......
编辑:
进一步研究,这个wikipedia链接详细介绍了零索引的几个很好且有趣的原因(这并没有直接说明为什么月份是零索引的,但我认为这已经被涵盖了),并且这个SO链接已经回答了之前的问题。
看起来流行的观点要么是“历史事故”,要么是“因为月份不是数字,所以不能与日/年存储进行比较”,具体取决于你问的是谁。
* 对不起,对不起,物理!=数学又回来咬我了。现在去熨烫我的手。