C'è un motivo per cui il primo elemento di un array Zsh è indicizzato da 1 anziché 0?


27

Dalla mia esperienza con i moderni linguaggi di programmazione e scripting, credo che la maggior parte dei programmatori sia generalmente abituata a riferirsi al primo elemento di un array per 0 come indice.
Ci sono dei vantaggi sostanziali nell'uso di 1 ?

Sono sicuro di aver sentito parlare di più lingue diverse da Zsh che si comportano in modo simile con gli array; per me va bene, poiché è altrettanto conveniente.
Tuttavia, poiché i linguaggi di shell shell precedentemente rilasciati e ampiamente usati come ksh e bash usano tutti 0, perché qualcuno dovrebbe scegliere di modificare questo "standard" comune?

La mia risposta immediata alla mia domanda sarebbe "ovviamente no";
quindi, l'unica spiegazione che mi viene in mente riguardo a questa "caratteristica esclusiva" per le shell sarebbe "l' hanno fatto solo per sfoggiare un po 'di più la loro fantastica shell ".

Non conosco molto né di Zsh né della sua storia, e c'è un'alta probabilità che la mia banale teoria su questo non abbia alcun senso.

C'è una spiegazione per questo? O è solo per gusto personale?


5
Alcune ricerche storiche (o ruminazioni rantish?) Sull'argomento 0 contro 1: exple.tive.org/blarg/2013/10/22/citation-needed
thrig

Per motivi storici, probabilmente viene da questo csh, che utilizzava anche l'indicizzazione di array basato su uno.
cuonglm,

3
oggigiorno sh è un linguaggio standard (non un'implementazione) con diversi possibili interpreti. Alcuni di quegli interpreti per il linguaggio sh come bash, ksh e yash supportano gli array come estensione, ma non fanno parte del linguaggio proprio come gcc, un compilatore per il linguaggio C standard supporta estensioni rispetto al linguaggio C standard. E proprio come per C, non esiste un'implementazione "ufficiale" di un interprete "sh".
Stéphane Chazelas,

1
Correlati - commenti in questa risposta PPCG
Digital Trauma

4
Forse un po 'fuori tema, ma rilevante. I romani usavano il conteggio inclusivo, fissando da uno invece di zero. Dopodomani, per noi "due giorni avanti", era per loro "tre giorni avanti". Hanno contato oggi come uno, non zero. Di conseguenza, quando i loro astronomi egiziani raccomandarono un giorno bisestile ogni quattro anni, i romani lo introdussero effettivamente ogni tre anni, a partire dal 45 a.C. Ci sono voluti fino al 12 a.C.per correggere l'errore.
Harry Weston,

Risposte:


32
  • Praticamente tutti gli array di shell (Bourne, csh, tcsh, fish, rc, es, yash) iniziano da 1. ksh è l'unica eccezione che conosco (bash ha appena copiato ksh).
  • Lingue più interpretati al momento (primi anni '90): awk, tclalmeno, e gli strumenti tipicamente utilizzati dalla shell ( cut -f1-3, head -n 3, sort -k1,3, cal 1 2015, comm -1) partono da 1. sed, ed, vinumero loro linee da 1 ...
  • zsh prende il meglio della shell Bourne e csh. L'array di shell Bourne $@inizia da 1. zsh è coerente con la sua gestione di $@(come in Bourne) o $argv(come in csh). Guarda come è confuso kshdove ${@:0:1}non ti dà il primo parametro posizionale per esempio.
  • Una shell è uno strumento utente prima di essere un linguaggio di programmazione. Ha senso per la maggior parte degli utenti avere il primo elemento in $a[1]. Significa anche che il numero di elementi è uguale all'ultimo indice (in zsh come nella maggior parte delle altre shell tranne ksh, le matrici non sono sparse).
  • a[1]per il primo elemento è coerente con a[-1]per l'ultimo.

Quindi la domanda dell'IMO dovrebbe piuttosto essere: che cosa è entrato nella testa di David Korn per far iniziare le sue matrici a 0?


7
È un bug nei linguaggi umani che la numerazione è basata su una sola e notevole serendipità che la maggior parte dei linguaggi di programmazione è riuscita a mantenere quell'eredità fuori dal loro design. Tanto più triste che, dopo che l' indicizzazione in base zero è stata praticamente stabilita come standard, così tante lingue "orientate all'utente" hanno ottenuto il contrario, cercando di essere "più semplice" usando di nuovo l'indicizzazione errata basata su una sola base. - Detto questo: il modo migliore per evitare la confusione dell'indicizzazione è ovviamente quello di evitare del tutto gli indici numerici.
circa il

Leggendo qui: "Quando si ha a che fare con una sequenza di lunghezza N, gli elementi di cui si desidera distinguere per pedice, ... a) produce, quando si inizia con il pedice 1, l'intervallo del pedice 1 ≤ i <N + 1; a partire da 0, tuttavia, fornisce l'intervallo migliore 0 ≤ i <N . " . Non so se TROLL o STUPID, ma puoi usare "1 ≤ i ≤ N" per i pedici che iniziano con 1 su array. Non è necessario inserire quel +1 alla fine della scansione dell'array e nessuno dei due punti di vista dimostra che gli indici di partenza con 1 o 0 sono migliori.

1
Puoi giustificare che 0 è stato aggiunto DOPO la conoscenza umana e che in qualche modo ha incasinato le cose. theguardian.com/notesandqueries/query/0,5753,-1358,00.html - Ancora una volta, solo una questione di punto di vista :)

3
L'array di shell Bourne $ @ inizia da 0 (non 1) $ 0 è il nome del programma in esecuzione. dovresti correggere il tuo terzo punto
Edward Torvalds,

2
@edwardtorvalds, No, $0non è un parametro posizionale. Non fa parte di $@. "$@"lo è "$1" "$2" .... Quando si tratta di funzioni, in molte shell, si vede che "$@"sono gli argomenti della funzione, mentre $0rimane il percorso dello script (o shell argv [0] quando non si esegue uno script)
Stéphane Chazelas,

7

Penso che la risposta più plausibile a questo sia l'array inverso incorporato da zsh

Se hai un array con 4 elementi, diciamo myvar=(1 2 3 4)e vuoi accedere al 4 ° elemento print $myvar[4], giusto?

Tuttavia, se si desidera creare un ciclo che elencherà gli elementi all'interno di questo array all'indietro, si tratta solo di utilizzare indici negativi:

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

Questo dovrebbe spiegare dal momento che partendo da zero, non raggiungerai uno di quegli elementi in quanto non esiste -0.

La seconda ragione dietro questo è probabilmente il codice C relativo alle variabili su zsh sta usando into double intper definire gli indici di array, e poiché usa il complemento a due per rappresentare numeri negativi non c'è modo di rappresentare -0( zero con segno ), come si può fare su float variabili punto.

Se sei veramente abituato agli indici a partire da 0, ti suggerisco di usare l' KSH_ARRAYSopzione per risolvere questo problema.

E prendendo il gancio del commento di @cuonglm, le cshfunzionalità implementate su zshsono spiegate qui . Sembra non essere una ragione storica ma un modo per fornire un ambiente di lavoro confortevole per coloro che sono abituaticsh


3
Quindi, questo dovrebbe farti accedere contemporaneamente al primo e all'ultimo elemento dell'array, rompendo tutta la logica della scansione di un array;) Potrebbe persino creare un blackhole. LOL

3
per gli array con indice 0, sostituire -con ~.
Mikeserv,

1
@mfxx - stavo parlando bash. penso che gestisca gli indici negativi per gli elementi impostati come zucchero di sintassi, ma altrimenti non lo fa. non ricordo. dal mio punto di vista, le persone dovrebbero semplicemente creare una directory e usare i file per qualsiasi cosa stiano inserendo in tutto quello stato di shell. puoi indicizzare quegli elementi nel modo che preferisci.
Mikeserv,

1
~è inversione binaria. ~0lo è -1. (tutti i bit capovolti si basano sul modo in cui i numeri negativi sono generalmente rappresentati bit-saggio). Su un array non impostato o su un array con solo un elemento di indice 0, uno [0], un [-0], un [-1] e un [~ 0] ti darà la stessa cosa in un array simile a ksh.
Stéphane Chazelas,

1
@ StéphaneChazelas - sì, penso di ricordare di averlo maneggiato ~quando -indexnon funzionava. Probabilmente tutto ciò che ho fatto è stato ~-index. si. sembra giusto. sì! e ovviamente funziona anche per elementi non impostati. quindi immagino che il commento sopra dovrebbe essere - per gli array con indice 0 aggiungere ~ . immagino che abbia semplicemente gestito la parte -1 forse più facilmente. non so. al momento non sta saltando in prima linea nella mia memoria ...
Mikeserv,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.