Apa asal penghitungan dari nol dalam bahasa pemrograman?

8

Ini adalah pertanyaan yang sudah lama saya tanyakan (dan pernah ditanyakan).

Dalam (kebanyakan? Semua?) Bahasa pemrograman, indeks dimulai dari nol untuk array, string, dll. Saya mengenalinya menjadi konvensi dari waktu ke waktu, diadopsi dalam banyak bahasa, tetapi adakah yang bisa menunjuk ke asal usul ini?

Saya pikir, mungkin itu ada hubungannya dengan semua yang berakar pada biner. Tetapi saya tidak yakin dengan ide yang membawa perlunya sistem desimal - mengapa tidak memulai indeks dari 1?

Adakah yang memiliki pengetahuan sejarah tentang bahasa pemrograman di mana keputusan untuk memulai indeks pada nol mungkin telah dijelaskan?

Terima kasih!

EDIT: Tulisan-tulisan Dijkstra lebih membantu dari sudut pandang matematika, tetapi bahkan ia telah mencatat, tidak semua bahasa diindeks nol. Penjelasan WBT juga masuk akal mengapa seseorang mulai dengan nol berdasarkan alamat memori. (Saya tahu beberapa bahasa menangani pengindeksan sedikit berbeda berdasarkan manipulasi array.)

Saya tidak perlu mencari mengapa (yang saya sangat hargai karena ini membantu lebih jauh pemahaman) tetapi lebih pada garis ketika ini menjadi konvensi dan / atau apakah itu dapat dilacak ke bahasa tertentu.

Jadi, misalnya dalam K&R C, ketika membahas indeks array, K atau R tanpa basa-basi menjelaskan, "Array subskrip selalu dimulai dari nol dalam C ..." (hlm. 22) Kemudian, dalam membahas fungsi untuk memproses karakter array, "... desain yang lebih berguna adalah mengembalikan panjang baris, atau nol jika akhir file ditemui. Nol adalah pengembalian file yang dapat diterima karena tidak pernah merupakan panjang baris yang valid." (hal. 127)

Berdasarkan K&R, saya mengumpulkan a) konvensi diadopsi dari tempat lain, jadi C bukanlah inspirasi di balik pengindeksan nol dan b) mungkin ada alasan yang lebih dalam untuk penggunaannya berdasarkan contoh kedua. Saya tahu K&R sangat dihormati karena prosa yang jelas, jadi itulah alasan saya memasukkannya, untuk memberikan contoh tentang apa yang saya harapkan akan dilakukan oleh bahasa terdokumentasi lain untuk menjelaskan alasan di balik pengindeksan nol.

Saya pikir WBT dan btilly menawarkan alasan yang sama baiknya; Saya bertanya-tanya apakah ada orang yang mungkin tahu bahasa lama (pra-C?) Yang mendokumentasikan keputusan desain. Dan pada saat yang sama saya mengenali informasi semacam itu mungkin tidak ada.

agas
sumber
3
Jawaban sederhana adalah bahwa ketika array adalah pointer, memiliki basis 0 adalah yang paling logis. Kemudian myarray [0] dan myarray + 0 adalah elemen yang sama, dan myarray [1] dan myarray + 1, dll. Anggap saja sebagai offset dari awal. Jawaban yang lebih terperinci mungkin akan datang jadi saya hanya menambahkan ini sebagai komentar :)
@ThomasH Itu tidak cukup "basis 0." Basis mengacu pada berapa banyak simbol unik yang mewakili nilai yang berbeda sebelum menambahkan posisi baru dalam angka. Basis dapat ditemukan dengan mencari tahu apa 10-1 dalam sistem itu. Basis 10 (desimal), basis 2 (biner), dan basis 16 (hex) adalah yang paling dikenal luas.
WBT
1
@WBT Anda akan berpikir bahwa jika Anda hanya membaca judulnya.
@ user6292850 Saya setuju ini referensi yang berguna, tapi saya rasa itu bukan penipuan.
WBT
3
Dijkstra menulis ini tentang nol indeks: cs.utexas.edu/users/EWD/transcription/EWD08xx/EWD831.html
Thomas Eding

Jawaban:

12

Ini tentang offset. Anda memiliki alamat, yang menunjuk ke lokasi di memori tempat array dimulai. Kemudian untuk mengakses elemen apa pun, Anda mengalikan indeks array dengan ukuran elemen dan menambahkannya ke alamat awal, untuk menemukan alamat untuk elemen itu.

Elemen pertama adalah pada titik awal, jadi Anda mengalikan ukuran elemen dengan nol untuk mendapatkan nol yang Anda tambahkan ke alamat awal untuk menemukan lokasi elemen pertama.

Konvensi menyebar karena programmer mulai bekerja dalam bahasa yang sangat rendah di mana alamat memori dimanipulasi secara langsung dan dalam kebanyakan kasus membangun dari sana, mempertahankan konvensi yang sama pada setiap langkah sehingga mereka tidak perlu mempelajari kembali atau rentan terhadap kesalahan ketika beralih antar konvensi. Masih penting untuk memahami bagaimana pengalamatan ini bekerja terutama ketika bekerja dengan bahasa tingkat rendah. Saya setuju ini bisa menjadi batu sandungan bagi orang-orang yang pertama kali belajar memprogram dalam bahasa tingkat yang lebih tinggi.

The artikel Wikipedia tentang topik ini juga mengutip instruksi mesin yang umum digunakan saat bekerja "mundur" dan mendeteksi akhir loop, yaitu "penurunan dan melompat jika nol."

Pengecualian: MATLAB dan beberapa bahasa lainnya melawan tren dan pergi dengan indeks mulai dari 1, tampaknya di bawah kesan bahwa itu akan menjadi bahasa pemrograman pertama bagi banyak pengguna target mereka dan bagi orang-orang itu, mulai dengan 1 membuat lebih banyak rasa intuitif. Hal ini menyebabkan beberapa frustasi untuk programmer (subset yang relatif kecil?) Yang sering beralih di antara bahasa pemrograman yang mulai menghitung pada nilai yang berbeda.

WBT
sumber
1
Iya. Tidak seorang pun yang pernah melakukan kontak dengan assembler akan mengajukan pertanyaan ini :)
Martin James
4

Pernyataan "Dalam (kebanyakan? Semua?) Bahasa pemrograman, indeks dimulai dari nol" sama sekali tidak benar. Bahasa-bahasa yang warisannya diturunkan secara formal atau tidak resmi dari C mengikuti konvensi ini. Orang lain mungkin tidak.

C melakukannya seperti itu karena C pada dasarnya dimaksudkan untuk menjadi perakit "tingkat tinggi". Itu menempatkan beban kerja yang adil pada programmer, di mana bahasa lain memiliki kompiler dan mesin melakukan pekerjaan berat. Pada saat C dikembangkan, penghitungan berbasis 1 adalah hal yang normal, tetapi mengharuskan kompiler untuk melacak tambahan konyol 1 itu dianggap terlalu banyak pekerjaan untuk kompiler.

C ++ mendapatkannya dari C karena persyaratan bahwa C ++ kompatibel dengan mundur (beberapa orang mungkin mengatakan bug-kompatibel) dengan C. Java mendapatkannya dari C. Bahasa yang dikembangkan oleh programmer C tanpa paparan signifikan terhadap apa pun yang disalin C, karena mereka juga ingin menjadi populer dengan programmer C lain atau mereka tidak tahu cara lain untuk melakukannya.

FORTRAN, yang mendahului hampir semua hal lain di luar sana, dimulai pada 1, karena insinyur, matematikawan, dan ilmuwan telah menghitung mulai dari 1 selama ribuan tahun. (Ini memungkinkan algoritma yang sangat ringkas, sangat bagus untuk masalah 8-queens.) MATLAB menyalin FORTRAN, karena ditujukan pada komunitas pengguna yang hampir sama persis.

PASCAL sebenarnya mengharuskan programmer untuk mengatakan di mana ia memulai dan selesai, memungkinkan seseorang untuk mendefinisikan, misalnya, dan array yang indeksnya berjalan dari, katakanlah, -7 hingga +7. Ada mengikuti PASCAL. (Menyebutkan Ada harus baik untuk setidaknya tiga downvote di sana.)

Saya percaya COBOL dimulai pada 1, tapi saya tidak ingat dengan pasti, dan saya tidak punya niat menyegarkan beberapa ingatan yang sangat menyakitkan, karena akuntan, seperti insinyur, ilmuwan, dan ahli matematika, mulai menghitung pada 1.

Ini adalah ingatan saya yang jauh bahwa PL / saya mengizinkan Anda untuk memulai dan berhenti di mana pun Anda suka. Pengungkapan Penuh: Saya tidak pernah melakukan pengkodean PL / I, hanya membaca sekilas sebuah buku, dan saya tidak punya niat untuk mengubahnya.

Saya tidak pernah menggunakan array di GPSS (paket simulasi peristiwa diskrit IBM), selama paparan singkat saya tentang hal itu, jadi saya tidak bisa memberi tahu Anda bagaimana GPSS melakukannya.

Bahasa assembly biasanya dimulai dari 0 karena array secara tradisional didefinisikan dalam hal alamat awal dan offset dari alamat awal. (Ini tidak selalu terjadi. IBM 1130 Executive memiliki tabel vektor residen besar, yang "alamat awal" -nya sebenarnya ada di tengah-tengah tabel. Mereka melakukan ini karena pengalamatan yang diindekskan pada indeks 1130 yang diizinkan menandatangani offset, yang memerlukan offset untuk memulai pada nol akan membuang setengah dari ukuran meja yang mungkin, dan meja itu PERLU menjadi besar.)

John R. Strohm
sumber
0

Mencoba jawaban singkat.

Menghitung dari nol populer tidak hanya dalam bahasa pemrograman tetapi dalam matematika lebih umum.

Menghitung jauh lebih tua dari nol. Karena nol dan notasi posisi ditemukan, semua orang menghitung 10s, 100s, 1000s dll dari nol: ini adalah digit terendah baru. Menghitung unit dari nol juga membawa beberapa keuntungan konsistensi, terutama dengan interval setengah terbuka dan array (multi-dimensi). Untuk detail dan contoh lebih lanjut lihat tautan di sisi kanan dan https://en.wikipedia.org/wiki/Zero-based_numbering

Maret
sumber
1
Angka berubah dari 0 menjadi 9, bukan dari 1 menjadi 10.
Ignacio Soler Garcia,
Dalam pengalaman saya, indeks dari 1 ke n lebih populer daripada indeks dari 0 ke n-1 dalam matematika.
CodesInChaos
-3

Setiap kemungkinan konvensi penghitungan telah dicoba. Penghitungan dari nol konvensi menjadi dominan karena alternatif cenderung lebih rentan kecelakaan.

Lihat https://www.cs.utexas.edu/users/EWD/transcription/EWD08xx/EWD831.html untuk satu penjelasan mengapa versi ini bekerja lebih baik.

btilly
sumber
2
Meskipun tautan ini dapat menjawab pertanyaan, lebih baik untuk memasukkan bagian-bagian penting dari jawaban di sini dan memberikan tautan untuk referensi. Jawaban hanya tautan dapat menjadi tidak valid jika halaman tertaut berubah. - Dari Ulasan
Vinoth Krishnan
6
"Setiap konvensi penghitungan yang memungkinkan telah dicoba." Apakah itu termasuk yang dimulai pada - e dan penambahan menurut unit π ?
WBT