Apakah ada alasan mengapa elemen pertama array Zsh diindeks oleh 1 bukannya 0?

27

Dari pengalaman saya dengan pemrograman modern dan bahasa scripting, saya percaya sebagian besar programmer umumnya terbiasa merujuk pada elemen pertama array dengan 0 sebagai indeks.
Apakah ada keuntungan substansial dalam menggunakan 1 ?

Saya yakin saya pernah mendengar lebih banyak bahasa selain Zsh yang berperilaku serupa dengan array; tidak masalah bagi saya, karena sama nyamannya.
Namun, seperti bahasa scripting shell yang sebelumnya dirilis dan banyak digunakan seperti ksh dan bash semua menggunakan 0, mengapa seseorang memilih untuk mengubah "standar" umum ini?

Jawaban langsung saya atas pertanyaan saya adalah "tentu saja tidak";
kemudian, satu-satunya penjelasan yang dapat saya pikirkan mengenai "fitur eksklusif" ini untuk kerang adalah " mereka hanya melakukan ini untuk memamerkan lebih banyak kerang keren mereka ".

Saya tidak tahu banyak tentang Zsh atau sejarahnya, dan ada kemungkinan besar teori sepele saya tentang ini tidak masuk akal.

Apakah ada penjelasan untuk ini? Atau hanya karena selera pribadi?

deekin
sumber
5
Beberapa penelitian sejarah (atau ruminasi rantish?) Pada topik 0 lawan 1: exple.tive.org/blarg/2013/10/22/citation-needed
thrig
Untuk alasan historis, itu mungkin berasal dari csh, yang juga menggunakan pengindeksan array berbasis satu.
cuonglm
3
Saat ini, sh adalah bahasa standar (bukan implementasi) yang memiliki penafsir yang berbeda. Beberapa penerjemah untuk bahasa sh seperti bash, ksh dan yash mendukung array sebagai ekstensi, tetapi mereka bukan bagian dari bahasa seperti gcc, sebuah kompiler untuk bahasa C standar mendukung ekstensi daripada bahasa C standar. Dan seperti halnya untuk C, tidak ada implementasi "resmi" dari juru bahasa "sh".
Stéphane Chazelas
1
Terkait - komentar dalam jawaban PPCG ini
Digital Trauma
4
Mungkin sedikit keluar dari topik, tetapi relevan. Bangsa Romawi menggunakan penghitungan yang inklusif, memandang dari satu alih-alih nol. Lusa, bagi kita "dua hari ke depan", bagi mereka "tiga hari ke depan." Mereka menghitung hari ini sebagai satu, bukan nol. Sebagai akibatnya ketika para astronom Mesir mereka merekomendasikan hari kabisat setiap tahun keempat, orang-orang Romawi benar-benar memperkenalkannya setiap tahun ketiga, dimulai pada 45 SM. Diperlukan waktu hingga 12 SM untuk memperbaiki kesalahan tersebut.
Harry Weston

Jawaban:

32
  • Hampir semua array shell (Bourne, csh, tcsh, fish, rc, es, yash) mulai dari 1. ksh adalah satu-satunya pengecualian yang saya tahu (bash hanya menyalin ksh).
  • Bahasa yang paling ditafsirkan pada saat itu (awal 90-an): awk, tclsetidaknya, dan alat-alat yang biasanya digunakan dari shell ( cut -f1-3, head -n 3, sort -k1,3, cal 1 2015, comm -1) mulai dari 1. sed, ed, vijumlah baris mereka dari 1 ...
  • zsh mengambil yang terbaik dari shell Bourne dan csh. Array shell Bourne $@mulai dari 1. zsh konsisten dengan penanganannya $@(seperti pada Bourne) atau $argv(seperti pada csh). Lihat betapa membingungkannya di kshmana ${@:0:1}tidak memberikan Anda parameter posisi pertama misalnya.
  • Shell adalah alat pengguna sebelum menjadi bahasa pemrograman. Masuk akal bagi sebagian besar pengguna untuk memiliki elemen pertama$a[1] . Ini juga berarti bahwa jumlah elemen sama dengan indice terakhir (dalam zsh seperti pada kebanyakan shell lain kecuali ksh, array tidak jarang).
  • a[1]untuk elemen pertama konsisten dengan a[-1]untuk yang terakhir.

Jadi IMO pertanyaannya seharusnya: apa yang masuk ke kepala David Korn untuk membuat array mulai dari 0?

Stéphane Chazelas
sumber
7
Ini adalah bug dalam bahasa manusia bahwa penomoran adalah berbasis satu, dan kebetulan luar biasa yang sebagian besar bahasa pemrograman berhasil menjaga warisan itu dari desain mereka. Semua sedih itu, setelah pengindeksan berbasis nol itu hampir ditetapkan sebagai standar, begitu banyak “berorientasi pengguna” bahasa mendapatkannya mundur, berusaha untuk menjadi “sederhana” dengan menggunakan salah , satu berbasis pengindeksan lagi. - Yang mengatakan: cara terbaik untuk menghindari kebingungan pengindeksan tentu saja untuk menghindari indeks numerik sepenuhnya.
leftaroundabout
Membaca di sini: "Ketika berhadapan dengan urutan panjang N, elemen yang ingin kita bedakan dengan subskrip, ... a) menghasilkan, ketika mulai dengan subskrip 1, kisaran subskrip 1 ≤ i <N +1; dimulai dengan Namun, 0 memberikan kisaran yang lebih baik 0 ≤ i <N . " . Tidak tahu apakah TROLL atau STUPID, tetapi Anda dapat menggunakan "1 ≤ i ≤ N" untuk subskrip yang dimulai dengan 1 pada array. Tidak perlu menempatkan +1 di akhir pemindaian array, dan tak satu pun dari sudut pandang membuktikan bahwa indeks awal dengan 1 atau 0 lebih baik.
1
Anda dapat membenarkan bahwa 0 ditambahkan SETELAH pengetahuan manusia, dan entah bagaimana itu mengacaukan hal-hal saat itu. theguardian.com/notesandqueries/query/0.5753,-1358,00.html - Sekali lagi, hanya masalah sudut pandang :)
3
Bourne shell array $ @ mulai dari 0 (bukan 1) $ 0 adalah nama program yang Anda jalankan. Anda harus mengoreksi poin ketiga Anda
Edward Torvalds
2
@edwardtorvalds, Tidak, $0bukan parameter posisi. Itu bukan bagian dari $@. "$@"adalah "$1" "$2" .... Ketika datang ke fungsi, di banyak shell, Anda melihat bahwa "$@"adalah argumen untuk fungsi, sementara $0tetap jalan skrip (atau shell argv [0] ketika tidak menjalankan skrip)
Stéphane Chazelas
7

Saya pikir jawaban yang paling masuk akal untuk ini adalah built-in dari array terbalik zsh

Jika Anda memiliki array dengan 4 elemen, katakanlah myvar=(1 2 3 4)dan Anda ingin mengakses elemen ke-4 print $myvar[4], kan?

Namun, jika Anda ingin membuat loop yang akan mencantumkan elemen-elemen di dalam array ini ke belakang, itu hanya masalah menggunakan indeks negatif:

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

Ini harus menjelaskan karena mulai dari nol, Anda tidak akan mencapai salah satu elemen tersebut karena tidak ada -0.

Alasan kedua di balik ini mungkin adalah kode C terkait dengan variabel pada zsh menggunakan intatau double intuntuk menentukan indeks array, dan karena menggunakan Komplemen Dua untuk mewakili angka negatif tidak ada cara untuk mewakili -0( Masuk nol ), seperti yang dapat Anda lakukan di float variabel titik.

Jika Anda benar-benar terbiasa dengan indeks mulai dari 0, saya sarankan Anda untuk menggunakan KSH_ARRAYSopsi untuk memperbaikinya.

Dan dengan mengaitkan komentar @cuonglm, cshfitur yang diimplementasikan zshdijelaskan di sini . Tampaknya bukan menjadi alasan historis tetapi cara untuk menyediakan lingkungan kerja yang nyaman bagi mereka yang terbiasa dengancsh


sumber
3
Kemudian, ini akan membuat Anda mengakses item array pertama dan terakhir pada saat yang sama, mematahkan semua logika pemindaian array;) Bahkan bisa membuat lubang hitam. LOL
3
untuk array 0-diindeks ganti -dengan ~.
mikeserv
1
@ mfxx - saya bicarakan bash. Saya pikir itu menangani indeks negatif untuk mengatur elemen sebagai gula sintaks, tetapi kemudian tidak melakukannya sebaliknya. tidak ingat. dari sudut pandang saya, orang hanya harus membuat direktori dan menggunakan file untuk apa pun yang mereka isikan ke semua negara shell Anda dapat mengindeks elemen-elemen itu dengan cara apa pun yang Anda suka.
mikeserv
1
~adalah inversi biner. ~0adalah -1. (semua bit terbalik, bergantung pada bagaimana bilangan negatif biasanya direpresentasikan dengan bijaksana). Pada array yang tidak disetel atau array dengan hanya satu elemen indice 0, a [0], a [-0], a [-1] dan [~ 0] akan memberi Anda hal yang sama dalam array seperti ksh.
Stéphane Chazelas
1
@ StéphaneChazelas - yeah, saya pikir saya ingat menangani ini ~ketika -indextidak berfungsi. Saya kira mungkin yang saya lakukan adalah ~-index. ya. kedengarannya benar. iya nih! dan tentu saja itu berfungsi untuk elemen yang tidak disetel juga. jadi saya kira komentar di atas harus - untuk menambahkan array 0-diindeks ~. Saya kira itu hanya menangani -1 bagian mungkin lebih mudah. saya tidak tahu. itu tidak melompat ke garis depan ingatan saya saat ini ...
mikeserv