Zsh 数组的第一个元素索引为 1 而不是 0 是否有原因?

Zsh 数组的第一个元素索引为 1 而不是 0 是否有原因?

根据我使用现代编程和脚本语言的经验,我相信大多数程序员通常习惯将数组的第一个元素称为索引 0(零)。

我确信我听说过除了zsh在 1 (一) 上开始数组索引之外的其他语言;没关系,因为同样方便。然而,由于之前发布并广泛使用的 shell 脚本语言kshbash使用 0,为什么有人会选择改变这个通用约定呢?

使用1作为第一个索引似乎没有什么实质性的优势;那么,我能想到的关于 shell 的这种有点“专有功能”的唯一解释是“他们这样做只是为了更多地展示他们很酷的 shell”。

不过,我对其中任何一个或其历史都了解不多zsh,而且我对此的琐碎理论很可能没有任何意义。

对此有解释吗?或者只是出于个人品味?

答案1

  • 几乎所有 shell 数组(Bourne、csh、tcsh、fish、rc、es、yash)都从 1 开始。ksh 是我所知道的唯一例外(bash 只是复制了 ksh)。
  • 当时(90 年代初)大多数解释语言:awktcl至少,通常在 shell 中使用的工具 ( cut -f1-3, head -n 3, sort -k1,3, cal 1 2015, comm -1) 从 1 开始。sed, edvi从 1 开始对行进行编号...
  • zsh 充分利用了 Bourne shell 和 csh 的优点。 Bourne shell 数组从 1 开始。zsh 与其处理(如在 Bourne 中)或(如在 csh 中)$@一致。例如,看看where没有给你第一个位置参数是多么令人困惑。$@$argvksh${@:0:1}
  • shell 在成为编程语言之前是一种用户工具。对于大多数用户来说,拥有第一的中的元素$a[1].这也意味着元素的数量与最后一个索引相同(在 zsh 中,与除 ksh 之外的大多数其他 shell 一样,数组是不是疏)。
  • a[1]a[-1]第一个元素与最后一个元素一致。

所以在我看来,问题应该是:为什么 David Korn 选择使其数组从 0 开始?

关于你的:

“但是,由于之前发布并广泛使用的 shell 脚本语言 ksh 和 bash 都使用 0”

请注意,虽然 bash 确实比 zsh 早几个月发布(1989 年 6 月与 1990 年 12 月相比),但在各自的 2.0 版本中添加了数组支持,但 zsh 是在 1991 年发布的,而 bash 是在 1996 年晚些时候发布的。

第一个引入数组的 Unix shell(除非您想考虑 1970 年代的 Thompson shell 及其$1..$2位置参数)是 70 年代末的 csh,其索引从 1 开始。它的代码是免费提供的,而 ksh 是专有的,并且直到 80 年代末才默认包含在 Unices 中(以高昂的价格单独出售)。虽然 ksh93 代码在 2000 年左右作为开源代码发布,但 ksh88 的代码迄今为止从未开源(尽管如果您对考古学感兴趣,今天在 archive.org 上找到 ksh86a 和 ksh88d 源代码并不难)。

答案2

我认为最合理的答案是内置的反向数组zsh

如果你有一个包含 4 个元素的数组,假设myvar=(1 2 3 4)你想访问第 4 个元素print $myvar[4],对吧?

但是,如果您想创建一个循环来向后列出该数组中的元素,只需使用负索引即可:

print $myvar[-1]   # will print 4
print $myvar[-2]   # will print 3
print $myvar[-3]   # will print 2
print $myvar[-4]   # will print 1

这应该可以解释,因为从零开始,您将不会到达这些元素之一,因为没有-0.

这背后的第二个原因可能是与 zsh 上的变量相关的 C 代码正在使用intordouble int来定义数组索引,并且因为它使用补码要表示负数,无法表示-0(签名零),就像您可以对浮点变量执行的操作一样。

如果您真的习惯从 0 开始的索引,我建议您使用该KSH_ARRAYS选项来修复此问题。

并以@cuonglm评论为钩子,解释了csh其实现的功能zsh这里。这似乎不是一个历史原因,而是一种为那些习惯于工作的人提供舒适的工作环境的方法。csh

相关内容