Чи є причина, чому перший елемент масиву Zsh індексується 1, а не 0?


27

З мого досвіду сучасних мов програмування та сценаріїв, я вважаю, що більшість програмістів зазвичай звикли посилатись на перший елемент масиву 0 як на індекс.
Чи є суттєві переваги використання 1 ?

Я впевнений, що я чув про більше мов, крім Zsh, що поводяться аналогічно з масивами; це добре мені, як це однаково зручно.
Однак, коли раніше випущені та широко використовувані мови сценаріїв оболонок, такі як ksh та bash, використовують 0, чому б хтось вирішив змінити цей загальний "стандарт"?

Моєю негайною відповіддю на моє запитання було б «звичайно, ні»;
то, єдине пояснення, про яке я можу подумати щодо цієї дещо «ексклюзивної особливості» снарядів, було б « вони просто зробили це, щоб показати трохи більше своєї крутої оболонки ».

Я мало знаю ні Zsh, ні його історію, і є велика ймовірність, що моя тривіальна теорія про це не має жодного сенсу.

Чи є для цього пояснення? Або це просто з особистого смаку?


5
Деякі історичні дослідження (чи несамовиті романи?) На тему 0 проти 1: exple.tive.org/blarg/2013/10/22/citation-needed
триг

З історичної причини це, ймовірно, походило csh, що також використовувало одноосновну індексацію масивів.
cuonglm

3
нині sh - це стандартна мова (а не реалізація), яка має різні можливі перекладачі. Деякі з цих інтерпретаторів для мови sh, такі як bash, ksh та yash, підтримують масиви як розширення, але вони не є частиною мови, як gcc, компілятор для стандартної мови C підтримує розширення над стандартною мовою C. І так само, як і для C, немає "офіційної" реалізації "ш" перекладача.
Стефан Шазелас


4
Можливо, трохи поза темою, але актуально. Римляни використовували інклюзивний підрахунок, дивлячись на один, а не на нуль. Післязавтра, нам "на два дні вперед", було їм "на три дні вперед". Сьогодні вони рахували як один, а не нуль. Як наслідок, коли їхні єгипетські астрономи рекомендували перехідний день кожен четвертий рік, римляни насправді впроваджували його кожен третій рік, починаючи з 45 р. До н. Виправлення помилки тривало до 12 до н.е.
Гаррі Вестон

Відповіді:


32
  • Практично всі масиви оболонок (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]останнім.

Таким чином, питання IMO швидше має бути таким: що потрапило в голову Девіда Корна, щоб його масиви починалися з 0?


7
Це помилка в людських мовах, що нумерація є одноосновною, і надзвичайна serendipity, що більшості мов програмування вдалося зберегти цю спадщину поза їх дизайном. Сумніше, що після нульової індексації практично було встановлено як стандарт, так багато мов, орієнтованих на користувачів, отримали її назад, намагаючись бути "простішою", використовуючи знову неправильну , одноосновну індексацію. - Це означає: найкращий спосіб уникнути плутанини в індексах - це, звичайно, уникати числових індексів цілком.
Ліворуч близько

Читаючи тут: "Маючи справу з послідовністю довжини N, елементи якої ми хочемо розрізнити за індексом, ... а) виходить, коли починається з індексту 1, діапазон підрядника 1 ≤ i <N + 1; починаючи з 0, однак, дає приємніший діапазон 0 ≤ i <N. " . Не знаєте, чи TROLL чи STUPID, але ви можете використовувати "1 ≤ i ≤ N" для підписок, починаючи з 1 на масивах. Не потрібно ставити цей +1 у кінці сканування масиву, і жодна з точок зору не підтверджує, що стартові індекси з 1 або 0 є кращими.

1
Можна або виправдати, що 0 було додано ПІСЛЯ до людських знань, і це якимось чином зіпсувало речі того часу. theguardian.com/notesandqueries/query/0,5753,-1358,00.html - Знову лише питання точки зору :)

3
Масив оболонки Bourne $ @ починається з 0 (не 1) $ 0 - це назва програми, яку ви запускаєте. ви повинні виправити свій третій пункт
Едвард Торвальдс

2
@edwardtorvalds, Ні, $0це не позиційні параметри. Це не частина $@. "$@"є "$1" "$2" .... Що стосується функцій, то в багатьох оболонках ви бачите, що "$@"це аргументи функції, при цьому $0залишається шлях сценарію (або оболонки argv [0], коли сценарій не виконується)
Stéphane Chazelas

7

Думаю, найбільш правдоподібною відповіддю на це є вбудований зворотний масив 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.

Друга причина цього - це, мабуть, код C, пов'язаний зі змінними на zsh, використовує intабо double intвизначає індекси масиву, і оскільки він використовує Complement Two для представлення негативних чисел, немає ніякого способу представити -0( підписаний нуль ), як це можна зробити на float точкові змінні.

Якщо ви дійсно звикли до індексів, починаючи з 0, я пропоную вам скористатися KSH_ARRAYSопцією, щоб виправити це.

І, беручи до уваги коментар @cuonglm, тут пояснюються cshфункції, реалізовані на . Здається, це не історична причина, а спосіб забезпечити комфортне робоче середовище для тих, хто звикzshcsh


3
Тоді це має змусити вас одночасно отримувати доступ до першого та останнього елементів масиву, порушуючи всю логіку сканування масиву;) Можна навіть створити чорний отвір. LOL

3
для 0-індексовані масиви замінити -з ~.
mikeserv

1
@mfxx - я говорив про це bash. Я думаю, що він обробляє негативні індекси для заданих елементів як синтаксичний цукор, але потім не робить цього інакше. не пам'ятаю. з моєї точки зору, люди повинні просто створити каталог і використовувати файли для того, що вони заповнюють, у весь цей стан оболонки. ви можете проіндексувати ці елементи будь-яким способом.
mikeserv

1
~є бінарною інверсією. ~0є -1. (усі біти перевернуті, залежать від того, як негативні числа зазвичай представлені бітними). Для невстановленого масиву або масиву, що містить лише один елемент індексу 0, a [0], a [-0], a [-1] та [~ 0] дасть вам те саме в ksh-подібному масиві.
Стефан Шазелас

1
@ StéphaneChazelas - так, я думаю, я пам’ятаю, що впорався з цим, ~коли -indexне працював. Я здогадуюсь, мабуть, все, що я робив ~-index. так. це звучить правильно. так! і звичайно, що працює і для невстановлених елементів. тому я здогадуюсь, що коментар повинен бути вище - для 0-індексованих масивів додати ~ . Я здогадуюсь, що це просто обробили -1 частину легше, можливо. я не знаю. на даний момент це не стрибає на перший план моєї пам'яті ...
mikeserv
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.