Есть ли причина, почему первый элемент массива Zsh индексируется с 1, а не с 0?

Вопрос или проблема

Исходя из моего опыта работы с современными языками программирования и сценарного языка, я считаю, что большинство программистов обычно привыкли обращаться к первому элементу массива как к индексу 0 (ноль).

Я уверен, что слышал о языках, отличных от zsh, которые начинают индексацию массивов с 1 (один); это нормально, так как это равноудобно. Однако, поскольку ранее выпущенные и широко используемые языки сценариев оболочки ksh и bash оба используют 0, зачем кому-то было бы изменять эту общепринятую конвенцию?

Кажется, нет никаких существенных преимуществ в использовании 1 как первого индекса; тогда единственное объяснение, которое я могу придумать относительно этой несколько «эксклюзивной функции» для оболочек, будет заключаться в том, что «они просто сделали это, чтобы немного похвастаться своей классной оболочкой».

Тем не менее, я не знаю много о zsh или его истории, и есть высокая вероятность, что моя тривиальная теория об этом не имеет смысла.

Есть ли объяснение этому? Или это просто вопрос личного вкуса?

  • Практически все массивы оболочек (Bourne, csh, tcsh, fish, rc, es, yash) начинаются с 1. ksh — единственное исключение, о котором я знаю (bash просто скопировал ksh).
  • Большинство интерпретируемых языков того времени (начало 90-х): awk, tcl по меньшей мере, а также инструменты, обычно используемые из оболочки (cut -f1-3, head -n 3, sort -k1,3, cal 1 2015, comm -1) начинаются с 1. sed, ed, vi нумеруют свои строки, начиная с 1…
  • zsh берет лучшее от оболочки Bourne и csh. Единственный массив оболочки Bourne $@ начинается с $1. zsh последовательно обрабатывает $@ (как в Bourne) или $argv (как в csh). Посмотрите, как запутанно это выглядит в ksh, где ${@:0:1} не даст вам первый позиционный параметр, например.
  • Оболочка — это пользовательский инструмент перед тем, как стать языком программирования. Для большинства пользователей имеет смысл, чтобы первый элемент был в $a[1]. Это также означает, что количество элементов совпадает с последним индексом (в zsh, как и в большинстве других оболочек, кроме ksh, массивы не разреженные).
  • a[1] для первого элемента согласуется с a[-1] для последнего.

Так что, на мой взгляд, вопрос должен звучать скорее так: Почему Дэвид Корн решил начать индексацию своих массивов с 0?

Что касается вашего:

“Однако, поскольку ранее выпущенные и широко используемые языки сценариев оболочки ksh и bash оба используют 0”

Обратите внимание, что хотя bash был впервые выпущен за несколько месяцев до zsh (в июне 1989 года по сравнению с декабрем 1990 года), поддержка массивов была добавлена в их соответствующие версии 2.0, но для zsh это было выпущено в 1991 году, тогда как для bash — значительно позже, в 1996 году.

Первой оболочкой Unix, введшей массивы (если вы не хотите считать оболочку Thompson 1970-х с её позиционными параметрами $1..$2) была csh в конце 70-х годов, индексы которой начинаются с одного. И её код был свободно доступен, в то время как ksh был собственническим и часто не включался по умолчанию в Unix (продавался отдельно по высокой цене) до конца 80-х годов. Хотя код ksh93 был выпущен как открытый исходный код около 2000 года, код ksh88, до сих пор, никогда не был (хотя не слишком трудно найти исходный код ksh86a и ksh88d на archive.org сегодня, если вам интересно археология).

Я думаю, самое правдоподобное объяснение этому связано с встроенной функцией обратного массива в zsh

Если у вас есть массив из 4 элементов, скажем, myvar=(1 2 3 4), и вы хотите получить доступ к 4-му элементу, это будет print $myvar[4], верно?

Тем не менее, если вы хотите создать цикл, который перечисляет элементы этого массива в обратном порядке, это просто вопрос использования отрицательных индексов:

print $myvar[-1]   # выведет 4
print $myvar[-2]   # выведет 3
print $myvar[-3]   # выведет 2
print $myvar[-4]   # выведет 1

Это должно объяснить, поскольку начиная с нуля, вы не сможете получить доступ к одному из этих элементов, так как -0 не существует.

Вторая причина, стоящая за этим, вероятно, связана с тем, что код на C, относящийся к переменным в zsh, использует int или double int для определения индексов массива, и поскольку он использует Двоичное представление со знаком для представления отрицательных чисел, нет способа представить -0 (Подписанный ноль), как это можно сделать с переменными плавающей запятой.

Если вам действительно привычны индексы, начинающиеся с 0, я рекомендую вам использовать опцию KSH_ARRAYS для исправления этого.

И, воспользовавшись комментарием @cuonglm, функции csh, реализованные в zsh, объясняются здесь. Похоже, это не историческая причина, а способ предоставить удобную рабочую среду для тех, кто привык к csh.

Ответ или решение

Почему первый элемент массива в Zsh индексируется с 1 вместо 0?

Когда речь заходит о языках программирования и сценариев, большинство разработчиков привыкли к тому, что индексация массивов начинается с нуля. Однако в Zsh, как и во многих других командных оболочках, таких как Csh и Tcsh, первый элемент массива индексируется с 1. В этой статье мы подробно рассмотрим причины этого выбора и исторические контексты.

Историческая перспектива и традиция оболочек

Несмотря на то, что такие языки, как Ksh и Bash, индексируют массивы с 0, многие сценарные оболочки, существовавшие до их появления, использовали индексацию с 1. Например, Csh, который был разработан в конце 1970-х, стал первым Unix-скриптовым языком, внедрившим массивы с индексами, начинающимися с единицы. Эта традиция продолжалась и в других оболочках, таких как Fish и Rc.

Таким образом, Zsh выбрала индексацию с 1, чтобы быть согласованной с уже существующими оболочками и использовать подходы, к которым пользователи могли быть привычны. Такой подход также обеспечивает некоторую унификацию с позиционными параметрами, которые в Unix-оболочках начинаются с $1, что делает работу с массивами более интуитивной для пользователя.

Удобство для пользователя

Zsh, как оболочка, нацелена на удобство использования для конечного пользователя, а не исключительно на возможности программирования. Индексация с 1 позволяет пользователям проще управлять элементами массивов: например, если у вас есть массив длиной 4, последний элемент явно обозначается как $myvar[4], в то время как при индексации с 0 его индексом было бы 3. Это делает структуру более простой и понятной, особенно для тех, кто не является опытным программистом.

Отрицательные индексы

Zsh предлагает интересную функциональность с помощью отрицательных индексов. Например, при использовании массива myvar=(1 2 3 4), доступ к элементам можно получить следующим образом:

print $myvar[-1]   # выведет 4
print $myvar[-2]   # выведет 3

Преимущества отрицательных индексов становятся очевидными, когда нужно обратиться к элементам массива с конца. Если бы индексация начиналась с 0, попытка получить доступ к элементу с индексом -0 привела бы к путанице, так как такая индексация не имеет смысла в контексте отрицательных значений.

Параметры реализации

С точки зрения реализации, Zsh использует целочисленные индексы (int или double int), что накладывает ограничения на использование отрицательных значений в контексте массивов. В частности, из-за принципов представления чисел в памяти, использование двухкомплемента для отрицательных чисел исключает возможность создания индекса -0. Это дополнительное ограничение может быть одной из причин выбора индексации с 1.

Заключение

Таким образом, выбор индексации с 1 в Zsh можно объяснить несколькими факторами: исторической традицией в Unix-системах, удобством для конечного пользователя и особенностями реализации. Этот подход делает работу с массивами более интуитивной для большинства пользователей, которые уже знакомы с концепциями оболочек и позиционными параметрами.

Хотя удобство использования и пользовательские привычки являются основными причинами, нельзя забывать и о соображениях реализации — такими особенностями, как ограничение отрицательных индексов, значительно упрощается работа с массивами и позволяет избежать путаницы.

Таким образом, Zsh не просто выбирает альтернативную индексацию, но и делает это с учетом предшествующих практик и пользовательского опыта, что отражает философию облегчения работы с системой.

Оцените материал
Добавить комментарий

Капча загружается...