Sebuah penunjuk (array) adalah arah memori dan indeks adalah offset dari arah memori itu, sehingga elemen pertama dari penunjuk (array) adalah orang yang mengimbangi sama dengan 0.
D33pN16h7
3
@ Radhirsch karena ketika kita menghitung satu set objek, kita mulai dengan menunjuk pada suatu objek dan mengatakan "satu".
phoog
1
Orang Amerika menghitung lantai (lantai) bangunan dari satu di lantai dasar; Inggris menghitung dari nol (lantai dasar), naik ke lantai satu, kemudian lantai dua, dll.
Jonathan Leffler
Jawaban:
116
Dalam C, nama array pada dasarnya adalah sebuah pointer [tetapi lihat komentar] , referensi ke lokasi memori, dan dengan demikian ekspresi array[n]merujuk ke nelemen lokasi memori jauh dari elemen awal. Ini berarti bahwa indeks digunakan sebagai offset. Elemen pertama dari array persis terkandung di lokasi memori yang merujuk (0 elemen), sehingga harus dilambangkan sebagai array[0].
Nama array adalah nama array; bertentangan dengan kesalahpahaman umum, array bukanlah petunjuk dalam arti apa pun. Ekspresi array (seperti nama objek array) biasanya, tetapi tidak selalu , dikonversi menjadi pointer ke elemen pertama. Contoh: sizeof arrmenghasilkan ukuran objek array, bukan ukuran pointer.
Keith Thompson
Meskipun Anda jelas tidak bereaksi terhadap komentar @ KeithThompson, saya ingin Anda menggunakan kursus yang lebih menyinggung: " Dalam C, nama array pada dasarnya adalah sebuah pointer, referensi ke lokasi memori " - Tidak, itu bukan . Setidaknya tidak dalam sudut pandang generik. Sementara jawaban Anda sempurna menjawab pertanyaan dengan cara bagaimana 0 sebagai awal indeks itu penting, kalimat pertama jelas salah. Array tidak selalu membusuk ke pointer ke elemen pertamanya.
RobertS mendukung Monica Cellio
Kutipan dari standar C, (C18), 6.3.2.1/4: " Kecuali ketika itu adalah operan dari sizeofoperator, atau &operator unary , atau string literal yang digunakan untuk menginisialisasi array, ekspresi yang memiliki tipe" array tipe "dikonversi ke ekspresi dengan tipe" pointer to type "yang menunjuk ke elemen awal objek array dan bukan nilai. Jika objek array memiliki kelas penyimpanan terdaftar, perilaku tidak ditentukan. "
RobertS mendukung Monica Cellio
Juga pembusukan ini terjadi dengan cara yang lebih "implisit" atau "secara formal" daripada yang disarankan di sini; tidak ada kerusakan pada objek pointer di memori yang terlibat. Ini adalah objek dari pertanyaan ini: Apakah pembusukan array ke pointer berubah menjadi objek pointer? - Harap edit jawaban Anda agar sepenuhnya benar.
RobertS mendukung Monica Cellio
103
Pertanyaan ini diposting lebih dari setahun yang lalu, tetapi begini ...
Tentang alasan di atas
Sementara artikel Dijkstra (sebelumnya dirujuk dalam jawaban yang sekarang dihapus ) masuk akal dari perspektif matematika, itu tidak relevan ketika datang ke pemrograman.
Keputusan yang diambil oleh spesifikasi bahasa & perancang-kompiler didasarkan pada keputusan yang dibuat oleh perancang sistem komputer untuk mulai menghitung pada 0.
Untuk setiap basis b, b ^ N pertama
bilangan bulat non-negatif diwakili oleh digit N persis (termasuk nol di depan) hanya jika penomoran dimulai pada 0.
Ini dapat diuji dengan cukup mudah. Di base-2, ambil 2^3 = 8
nomor 8 adalah:
8 (biner: 1000) jika kita mulai menghitung 1
7 (biner: 111) jika kita mulai menghitung pada 0
111dapat direpresentasikan menggunakan 3bit, sementara 1000akan membutuhkan bit tambahan (4 bit).
Mengapa ini relevan?
Alamat memori komputer memiliki 2^Nsel yang ditangani oleh Nbit. Sekarang jika kita mulai menghitung pada 1, 2^Nsel akan membutuhkan N+1garis alamat. Bit ekstra diperlukan untuk mengakses tepat 1 alamat. ( 1000dalam kasus di atas.). Cara lain untuk menyelesaikannya adalah meninggalkan alamat terakhir tidak dapat diakses, dan menggunakan Nbaris alamat.
Keduanya merupakan solusi sub-optimal , dibandingkan dengan penghitungan mulai pada 0, yang akan membuat semua alamat dapat diakses, menggunakan Ngaris alamat yang tepat !
Kesimpulan
Keputusan untuk mulai menghitung 0, sejak itu meresapi semua sistem digital , termasuk perangkat lunak yang menjalankannya, karena membuatnya lebih mudah bagi kode untuk menerjemahkan apa yang dapat ditafsirkan oleh sistem yang mendasarinya. Jika tidak, akan ada satu operasi terjemahan yang tidak perlu antara mesin dan pemrogram, untuk setiap akses array. Itu membuat kompilasi lebih mudah.
Bagaimana jika mereka baru saja menghapus bit 0 .. maka nomor 8 masih akan menjadi 111 ...
DanMatlin
2
Apakah Anda benar-benar menyarankan modifikasi aritmatika dasar agar sesuai? Tidakkah Anda berpikir apa yang kita miliki hari ini adalah solusi yang jauh lebih baik?
Anirudh Ramanathan
Bertahun-tahun kemudian, nilai 2 cnt saya. Dalam pengalaman saya (~ 35 tahun pemrograman) modulo atau operasi penambahan modular dalam satu atau lain bentuk muncul secara mengejutkan sering. Dengan nol basis urutan berikutnya adalah (i + 1)% n tetapi dengan basis 1 ia datang (i-1)% n) +1, jadi saya pikir 0 berbasis lebih disukai. Ini muncul dalam matematika dan pemrograman cukup sering. Mungkin hanya saya atau bidang tempat saya bekerja.
nyholku
Sementara semua alasan bagus saya pikir itu jauh lebih sederhana: a[b]diimplementasikan seperti *(a+b)pada kompiler awal. Bahkan saat ini Anda masih dapat menulis 2[a]bukan a[2]. Sekarang jika indeks tidak dimulai pada 0 maka a[b]akan berubah menjadi *(a+b-1). Ini akan membutuhkan 2 tambahan pada CPU pada waktu bukan 0, yang berarti setengah dari kecepatan. Jelas tidak diinginkan.
Goswin von Brederlow
1
Hanya karena Anda ingin 8 negara bagian, itu tidak berarti Anda harus memiliki angka 8 di dalamnya. Sakelar lampu di rumah saya dengan senang hati menyatakan status "lampu menyala", "padam", tanpa pernah bertanya-tanya mengapa mereka tidak mewakili angka 2.
Spyryto
27
Karena 0 adalah seberapa jauh dari pointer ke kepala array ke elemen pertama array.
Mempertimbangkan:
int foo[5]={1,2,3,4,5};
Untuk mengakses 0 kami lakukan:
foo[0]
Tapi foo terurai menjadi pointer, dan akses di atas memiliki cara aritmatika pointer analog untuk mengaksesnya
*(foo +0)
Aritmatika penunjuk hari ini tidak sering digunakan. Namun ketika masih jauh, itu adalah cara yang mudah untuk mengambil alamat dan memindahkan X "ints" dari titik awal. Tentu saja jika Anda ingin tetap di tempat Anda sekarang, Anda tinggal menambahkan 0!
Anda memunculkan poin yang menarik. Ini dapat merusak kinerja. Tetapi apakah kinerja yang dicapai signifikan untuk membenarkan penggunaan 0 sebagai indeks awal? Aku meragukan itu.
FirstName LastName
3
@FirstNameLastName indeks berbasis 1 tidak menawarkan keuntungan lebih dari indeks berbasis 0 namun kinerjanya (sedikit) lebih buruk. Itu membenarkan indeks berbasis 0 tidak peduli seberapa "kecil" keuntungannya. Bahkan jika indeks berbasis 1 menawarkan beberapa keuntungan, itu adalah semangat C ++ untuk memilih kinerja daripada kenyamanan. C ++ kadang-kadang digunakan dalam konteks di mana setiap bit kinerja penting, dan hal-hal "kecil" ini dapat dengan cepat bertambah.
Branko Dimitrijevic
Ya, saya mengerti bahwa hal-hal kecil dapat bertambah dan terkadang menjadi hal besar. Misalnya, $ 1 per tahun tidak banyak uang. Tetapi, jika 2 miliar orang menyumbangkannya, maka kita dapat melakukan banyak hal baik untuk kemanusiaan. Saya mencari contoh serupa dalam pengkodean yang dapat menyebabkan kinerja yang buruk.
FirstName LastName
2
Daripada mengurangi 1, Anda harus menggunakan alamat array-1 sebagai alamat dasar. Itu yang kami lakukan di kompiler yang pernah saya kerjakan. Itu menghilangkan pengurangan runtime. Saat Anda menulis kompiler, instruksi tambahan itu sangat berarti. Compiler akan digunakan untuk menghasilkan ribuan program, yang masing-masingnya dapat digunakan ribuan kali, dan bahwa instruksi tambahan 1 dapat terjadi di beberapa baris di dalam n squared loop. Itu dapat menambahkan hingga miliaran siklus terbuang.
program
Tidak itu tidak akan merusak kinerja setelah dikompilasi, itu hanya akan menambah waktu membangun kecil karena pada akhirnya akan diterjemahkan ke kode mesin. Itu hanya akan merugikan desainer kompiler.
Hassaan Akbar
12
Karena itu membuat kompiler dan linker lebih sederhana (lebih mudah untuk menulis).
"... Mengacu memori dengan alamat dan offset diwakili langsung dalam perangkat keras pada hampir semua arsitektur komputer, jadi detail desain ini di C membuat kompilasi lebih mudah"
dan
"... ini membuat implementasi yang lebih sederhana ..."
+1 Tidak yakin mengapa suara turun. Meskipun tidak langsung menjawab pertanyaan, pengindeksan berbasis 0 tidak alami untuk orang atau ahli matematika - satu-satunya alasan dilakukan adalah karena implementasi konsisten secara logis (sederhana).
phkahler
4
@ phkahler: kesalahannya ada pada penulis dan bahasa yang memanggil indeks array sebagai indeks; jika Anda menganggapnya sebagai offset, maka berbasis 0 menjadi alami untuk orang awam juga. Pertimbangkan jamnya, menit pertama ditulis sebagai 00:00, bukan 00:01 bukan?
Lie Ryan
3
+1 - ini mungkin jawaban yang paling benar. C mendahului kertas Djikistras dan merupakan salah satu bahasa "awal pada 0" yang paling awal. C memulai kehidupan "sebagai assembler tingkat tinggi" dan kemungkinan bahwa K&R ingin menempel sedekat mungkin dengan yang dilakukan pada assembler di mana Anda biasanya akan memiliki alamat basis ditambah offset mulai dari nol.
James Anderson
Saya pikir pertanyaannya adalah mengapa 0 berbasis digunakan, bukan yang lebih baik.
progrmr
2
Saya tidak akan downvote tetapi sebagai progrmr berkomentar di atas basis dapat diurus dengan menyesuaikan alamat array sehingga terlepas dari waktu eksekusi basis sama dan ini sepele untuk diterapkan dalam kompiler atau juru bahasa sehingga tidak benar-benar membuat implementasi lebih sederhana . Saksikan Pascal tempat Anda dapat menggunakan rentang apa pun untuk mengindeks IIRC, sudah 25 tahun;)
nyholku
5
Indeks array selalu dimulai dengan nol. Mari kita asumsikan alamat basis adalah 2000. Sekarang arr[i] = *(arr+i). Sekarang if i= 0, ini berarti *(2000+0) sama dengan alamat dasar atau alamat elemen pertama dalam array. indeks ini diperlakukan sebagai offset, sehingga indeks bydeafault dimulai dari nol.
Untuk alasan yang sama bahwa, ketika hari Rabu dan seseorang bertanya berapa hari sampai hari Rabu, Anda mengatakan 0 daripada 1, dan bahwa ketika hari Rabu dan seseorang bertanya berapa hari hingga Kamis, Anda mengatakan 1 daripada 2.
Jawaban Anda sepertinya hanya masalah pendapat saja.
heltonbiker
6
Nah, itu yang membuat menambahkan indeks / offset bekerja. Misalnya jika "hari ini" adalah 0 dan "besok" adalah 1, "besok besok" adalah 1 + 1 = 2. Tetapi jika "hari ini" adalah 1 dan "besok" adalah 2, "besok besok" bukan 2 + 2. Dalam array, fenomena ini terjadi kapan pun Anda ingin mempertimbangkan subrange dari array sebagai array sendiri.
R .. GitHub BERHENTI MEMBANTU ICE
7
Menyebut koleksi 3 hal "3 hal" dan memberi angka 1,2,3 bukanlah kekurangan. Menomori mereka dengan offset dari yang pertama adalah tidak alami bahkan dalam matematika. Satu-satunya waktu Anda mengindeks dari nol dalam matematika adalah ketika Anda ingin memasukkan sesuatu seperti kekuatan nol-(istilah konstan) dalam polinomial.
phkahler
9
Re: "Array penomoran dimulai dengan 1 daripada 0 adalah untuk orang-orang dengan kekurangan pemikiran matematika." Edisi CLR "Introduction to Algorithms" CLR saya menggunakan pengindeksan array berbasis 1; Saya tidak berpikir penulis memiliki kekurangan dalam pemikiran matematika.
RexE
Tidak, saya akan mengatakan yang ketujuh ada di indeks 6, atau 6 posisi jauh dari yang pertama.
R .. GitHub BERHENTI MEMBANTU ICE
2
Penjelasan paling elegan yang pernah saya baca untuk penomoran berbasis nol adalah pengamatan bahwa nilai-nilai tidak disimpan di tempat-tempat yang ditandai pada garis bilangan, melainkan di ruang di antara mereka. Item pertama disimpan antara nol dan satu, item berikutnya antara satu dan dua, dll. Item N disimpan di antara N-1 dan N. Berbagai item dapat dijelaskan menggunakan angka-angka di kedua sisi. Masing-masing item berdasarkan konvensi dijelaskan menggunakan angka-angka di bawahnya. Jika seseorang diberi rentang (X, Y), mengidentifikasi nomor individual menggunakan angka di bawah ini berarti bahwa seseorang dapat mengidentifikasi item pertama tanpa menggunakan aritmatika (itu item X) tetapi seseorang harus mengurangi satu dari Y untuk mengidentifikasi item terakhir (Y -1). Mengidentifikasi item menggunakan nomor di atas akan membuatnya lebih mudah untuk mengidentifikasi item terakhir dalam suatu rentang (itu akan menjadi item Y),
Meskipun tidak akan mengerikan untuk mengidentifikasi item berdasarkan nomor di atasnya, mendefinisikan item pertama dalam rentang (X, Y) sebagai item di atas X umumnya bekerja lebih baik daripada mendefinisikannya sebagai yang di bawah ini (X + 1).
Alasan teknis mungkin berasal dari fakta bahwa penunjuk ke lokasi memori array adalah isi dari elemen pertama array. Jika Anda mendeklarasikan pointer dengan indeks satu, program biasanya akan menambahkan nilai itu ke pointer untuk mengakses konten yang bukan yang Anda inginkan, tentu saja.
Cobalah untuk mengakses layar piksel menggunakan koordinat X, Y pada matriks berbasis 1. Rumusnya sangat kompleks. Mengapa rumit? Karena Anda akhirnya mengonversi koordinat X, Y menjadi satu angka, offset. Mengapa Anda perlu mengonversi X, Y ke offset? Karena itulah cara memori diatur di dalam komputer, sebagai aliran sel memori (array) yang berkelanjutan. Bagaimana komputer menangani sel array? Menggunakan offset (perpindahan dari sel pertama, model pengindeksan berbasis nol).
Jadi pada titik tertentu dalam kode yang Anda butuhkan (atau kebutuhan kompilator) untuk mengubah rumus 1-basis menjadi rumus berbasis 0 karena itulah cara komputer menangani memori.
Misalkan kita ingin membuat array dengan ukuran 5
int array [5] = [2,3,5,9,8]
mari elemen pertama dari array diarahkan ke lokasi 100
dan mari kita pertimbangkan pengindeksan dimulai dari 1 bukan dari 0.
sekarang kita harus menemukan lokasi elemen 1 dengan bantuan indeks
(ingat lokasi elemen 1 adalah 100)
karena ukuran bilangan bulat adalah 4-bit
karena itu -> dengan mempertimbangkan indeks 1 posisi akan menjadi
ukuran of index (1) * size of integer (4) = 4
sehingga posisi aktual yang akan ditunjukkan kepada kita adalah
100 + 4 = 104
yang tidak benar karena lokasi awal berada pada 100.
seharusnya menunjuk ke 100 bukan pada 104
ini salah
sekarang misalkan kita telah mengambil pengindeksan dari 0
maka
posisi elemen 1 harus
ukuran indeks (0) * ukuran bilangan bulat (4) = 0
karena itu ->
lokasi elemen 1 adalah 100 + 0 = 100
dan itu adalah lokasi sebenarnya dari elemen
ini mengapa pengindeksan dimulai pada 0;
Saya dari latar belakang Java. Saya telah mempresentasikan jawaban untuk pertanyaan ini dalam diagram di bawah ini yang telah saya tulis di selembar kertas yang cukup jelas
Langkah Utama:
Membuat Referensi
Instansiasi Array
Alokasi Data ke array
Perhatikan juga ketika array baru saja dipakai .... Nol dialokasikan ke semua blok secara default sampai kami menetapkan nilai untuknya
Array dimulai dengan nol karena alamat pertama akan menunjuk ke referensi (i: e - X102 + 0 pada gambar)
Catatan : Blok yang ditunjukkan pada gambar adalah representasi memori
pertama-tama Anda perlu tahu bahwa array secara internal dianggap sebagai pointer karena "nama array itu sendiri berisi alamat elemen pertama array"
ex.int arr[2]={5,4};
pertimbangkan bahwa array dimulai pada alamat 100 sehingga elemen elemen pertama akan di alamat 100 dan yang kedua akan berada di 104 sekarang, pertimbangkan bahwa jika indeks array dimulai dari 1, maka
arr[1]:-
ini dapat ditulis dalam ekspresi pointer seperti ini-
arr[1]=*(arr +1*(size of single element of array));
pertimbangkan ukuran int adalah 4bytes, sekarang,
arr[1]=*(arr +1*(4));
arr[1]=*(arr +4);
seperti yang kita ketahui nama array berisi alamat elemen pertama sehingga arr = 100 sekarang,
arr[1]=*(100+4);
arr[1]=*(104);
pemberian yang mana,
arr[1]=4;
karena ungkapan ini kami tidak dapat mengakses elemen di alamat 100 yang merupakan elemen pertama resmi,
sekarang pertimbangkan indeks array mulai dari 0, jadi
arr[0]:-
ini akan diselesaikan sebagai
arr[0]=*(arr +0+(size of type of array));
arr[0]=*(arr +0*4);
arr[0]=*(arr +0);
arr[0]=*(arr);
sekarang, kita tahu bahwa nama array mengandung alamat elemen pertamanya jadi,
arr[0]=*(100);
yang memberikan hasil yang benar
arr[0]=5;
Oleh karena itu indeks array selalu dimulai dari 0 di c.
referensi: semua detail ditulis dalam buku "Bahasa pemrograman C oleh brian kerninghan dan dennis ritchie"
Nama array adalah pointer konstan yang menunjuk ke alamat basis. Ketika Anda menggunakan arr [i] kompiler memanipulasi sebagai * (arr + i). Karena kisaran int adalah -128 hingga 127, kompiler berpikir bahwa -128 ke -1 adalah angka negatif dan 0 hingga 128 adalah angka positif. Jadi indeks array selalu dimulai dengan nol.
Apa yang Anda maksud dengan 'kisaran int adalah -128 hingga 127' ? intDiperlukan suatu jenis untuk mendukung setidaknya kisaran 16-bit, dan pada kebanyakan sistem dewasa ini mendukung 32-bit. Saya pikir logika Anda cacat, dan jawaban Anda benar-benar tidak meningkat pada jawaban lain yang sudah disediakan oleh orang lain. Saya sarankan menghapus ini.
Jawaban:
Dalam C, nama array pada dasarnya adalah sebuah pointer [tetapi lihat komentar] , referensi ke lokasi memori, dan dengan demikian ekspresi
array[n]
merujuk ken
elemen lokasi memori jauh dari elemen awal. Ini berarti bahwa indeks digunakan sebagai offset. Elemen pertama dari array persis terkandung di lokasi memori yang merujuk (0 elemen), sehingga harus dilambangkan sebagaiarray[0]
.Untuk info lebih lanjut:
http://developeronline.blogspot.com/2008/04/why-array-index-should-start-from-0.html
sumber
sizeof arr
menghasilkan ukuran objek array, bukan ukuran pointer.sizeof
operator, atau&
operator unary , atau string literal yang digunakan untuk menginisialisasi array, ekspresi yang memiliki tipe" array tipe "dikonversi ke ekspresi dengan tipe" pointer to type "yang menunjuk ke elemen awal objek array dan bukan nilai. Jika objek array memiliki kelas penyimpanan terdaftar, perilaku tidak ditentukan. "Pertanyaan ini diposting lebih dari setahun yang lalu, tetapi begini ...
Tentang alasan di atas
Sementara artikel Dijkstra (sebelumnya dirujuk dalam jawaban yang sekarang dihapus ) masuk akal dari perspektif matematika, itu tidak relevan ketika datang ke pemrograman.
Alasan yang mungkin
Mengutip dari Permohonan Damai oleh Danny Cohen.
Ini dapat diuji dengan cukup mudah. Di base-2, ambil
2^3 = 8
nomor 8 adalah:111
dapat direpresentasikan menggunakan3
bit, sementara1000
akan membutuhkan bit tambahan (4 bit).Mengapa ini relevan?
Alamat memori komputer memiliki
2^N
sel yang ditangani olehN
bit. Sekarang jika kita mulai menghitung pada 1,2^N
sel akan membutuhkanN+1
garis alamat. Bit ekstra diperlukan untuk mengakses tepat 1 alamat. (1000
dalam kasus di atas.). Cara lain untuk menyelesaikannya adalah meninggalkan alamat terakhir tidak dapat diakses, dan menggunakanN
baris alamat.Keduanya merupakan solusi sub-optimal , dibandingkan dengan penghitungan mulai pada 0, yang akan membuat semua alamat dapat diakses, menggunakan
N
garis alamat yang tepat !Kesimpulan
Keputusan untuk mulai menghitung
0
, sejak itu meresapi semua sistem digital , termasuk perangkat lunak yang menjalankannya, karena membuatnya lebih mudah bagi kode untuk menerjemahkan apa yang dapat ditafsirkan oleh sistem yang mendasarinya. Jika tidak, akan ada satu operasi terjemahan yang tidak perlu antara mesin dan pemrogram, untuk setiap akses array. Itu membuat kompilasi lebih mudah.Mengutip dari kertas:
sumber
a[b]
diimplementasikan seperti*(a+b)
pada kompiler awal. Bahkan saat ini Anda masih dapat menulis2[a]
bukana[2]
. Sekarang jika indeks tidak dimulai pada 0 makaa[b]
akan berubah menjadi*(a+b-1)
. Ini akan membutuhkan 2 tambahan pada CPU pada waktu bukan 0, yang berarti setengah dari kecepatan. Jelas tidak diinginkan.Karena 0 adalah seberapa jauh dari pointer ke kepala array ke elemen pertama array.
Mempertimbangkan:
Untuk mengakses 0 kami lakukan:
Tapi foo terurai menjadi pointer, dan akses di atas memiliki cara aritmatika pointer analog untuk mengaksesnya
Aritmatika penunjuk hari ini tidak sering digunakan. Namun ketika masih jauh, itu adalah cara yang mudah untuk mengambil alamat dan memindahkan X "ints" dari titik awal. Tentu saja jika Anda ingin tetap di tempat Anda sekarang, Anda tinggal menambahkan 0!
sumber
Karena indeks berbasis 0 memungkinkan ...
... untuk diimplementasikan sebagai ...
Jika indeks berbasis 1, kompiler harus menghasilkan:,
*(array + index - 1)
dan "-1" ini akan merusak kinerja.sumber
Karena itu membuat kompiler dan linker lebih sederhana (lebih mudah untuk menulis).
Referensi :
dan
sumber
Indeks array selalu dimulai dengan nol. Mari kita asumsikan alamat basis adalah 2000. Sekarang
arr[i] = *(arr+i)
. Sekarangif i= 0
, ini berarti*(2000+0
) sama dengan alamat dasar atau alamat elemen pertama dalam array. indeks ini diperlakukan sebagai offset, sehingga indeks bydeafault dimulai dari nol.sumber
Untuk alasan yang sama bahwa, ketika hari Rabu dan seseorang bertanya berapa hari sampai hari Rabu, Anda mengatakan 0 daripada 1, dan bahwa ketika hari Rabu dan seseorang bertanya berapa hari hingga Kamis, Anda mengatakan 1 daripada 2.
sumber
Penjelasan paling elegan yang pernah saya baca untuk penomoran berbasis nol adalah pengamatan bahwa nilai-nilai tidak disimpan di tempat-tempat yang ditandai pada garis bilangan, melainkan di ruang di antara mereka. Item pertama disimpan antara nol dan satu, item berikutnya antara satu dan dua, dll. Item N disimpan di antara N-1 dan N. Berbagai item dapat dijelaskan menggunakan angka-angka di kedua sisi. Masing-masing item berdasarkan konvensi dijelaskan menggunakan angka-angka di bawahnya. Jika seseorang diberi rentang (X, Y), mengidentifikasi nomor individual menggunakan angka di bawah ini berarti bahwa seseorang dapat mengidentifikasi item pertama tanpa menggunakan aritmatika (itu item X) tetapi seseorang harus mengurangi satu dari Y untuk mengidentifikasi item terakhir (Y -1). Mengidentifikasi item menggunakan nomor di atas akan membuatnya lebih mudah untuk mengidentifikasi item terakhir dalam suatu rentang (itu akan menjadi item Y),
Meskipun tidak akan mengerikan untuk mengidentifikasi item berdasarkan nomor di atasnya, mendefinisikan item pertama dalam rentang (X, Y) sebagai item di atas X umumnya bekerja lebih baik daripada mendefinisikannya sebagai yang di bawah ini (X + 1).
sumber
Alasan teknis mungkin berasal dari fakta bahwa penunjuk ke lokasi memori array adalah isi dari elemen pertama array. Jika Anda mendeklarasikan pointer dengan indeks satu, program biasanya akan menambahkan nilai itu ke pointer untuk mengakses konten yang bukan yang Anda inginkan, tentu saja.
sumber
Cobalah untuk mengakses layar piksel menggunakan koordinat X, Y pada matriks berbasis 1. Rumusnya sangat kompleks. Mengapa rumit? Karena Anda akhirnya mengonversi koordinat X, Y menjadi satu angka, offset. Mengapa Anda perlu mengonversi X, Y ke offset? Karena itulah cara memori diatur di dalam komputer, sebagai aliran sel memori (array) yang berkelanjutan. Bagaimana komputer menangani sel array? Menggunakan offset (perpindahan dari sel pertama, model pengindeksan berbasis nol).
Jadi pada titik tertentu dalam kode yang Anda butuhkan (atau kebutuhan kompilator) untuk mengubah rumus 1-basis menjadi rumus berbasis 0 karena itulah cara komputer menangani memori.
sumber
Misalkan kita ingin membuat array dengan ukuran 5
int array [5] = [2,3,5,9,8]
mari elemen pertama dari array diarahkan ke lokasi 100
dan mari kita pertimbangkan pengindeksan dimulai dari 1 bukan dari 0.
sekarang kita harus menemukan lokasi elemen 1 dengan bantuan indeks
(ingat lokasi elemen 1 adalah 100)
karena ukuran bilangan bulat adalah 4-bit
karena itu -> dengan mempertimbangkan indeks 1 posisi akan menjadi
ukuran of index (1) * size of integer (4) = 4
sehingga posisi aktual yang akan ditunjukkan kepada kita adalah
100 + 4 = 104
yang tidak benar karena lokasi awal berada pada 100.
seharusnya menunjuk ke 100 bukan pada 104
ini salah
sekarang misalkan kita telah mengambil pengindeksan dari 0
maka
posisi elemen 1 harus
ukuran indeks (0) * ukuran bilangan bulat (4) = 0
karena itu ->
lokasi elemen 1 adalah 100 + 0 = 100
dan itu adalah lokasi sebenarnya dari elemen
ini mengapa pengindeksan dimulai pada 0;
Saya harap ini akan menjelaskan maksud Anda.
sumber
Saya dari latar belakang Java. Saya telah mempresentasikan jawaban untuk pertanyaan ini dalam diagram di bawah ini yang telah saya tulis di selembar kertas yang cukup jelas
Langkah Utama:
Catatan : Blok yang ditunjukkan pada gambar adalah representasi memori
sumber
pertama-tama Anda perlu tahu bahwa array secara internal dianggap sebagai pointer karena "nama array itu sendiri berisi alamat elemen pertama array"
pertimbangkan bahwa array dimulai pada alamat 100 sehingga elemen elemen pertama akan di alamat 100 dan yang kedua akan berada di 104 sekarang, pertimbangkan bahwa jika indeks array dimulai dari 1, maka
ini dapat ditulis dalam ekspresi pointer seperti ini-
pertimbangkan ukuran int adalah 4bytes, sekarang,
seperti yang kita ketahui nama array berisi alamat elemen pertama sehingga arr = 100 sekarang,
pemberian yang mana,
karena ungkapan ini kami tidak dapat mengakses elemen di alamat 100 yang merupakan elemen pertama resmi,
sekarang pertimbangkan indeks array mulai dari 0, jadi
ini akan diselesaikan sebagai
sekarang, kita tahu bahwa nama array mengandung alamat elemen pertamanya jadi,
yang memberikan hasil yang benar
Oleh karena itu indeks array selalu dimulai dari 0 di c.
referensi: semua detail ditulis dalam buku "Bahasa pemrograman C oleh brian kerninghan dan dennis ritchie"
sumber
Dalam array, indeks memberi tahu jarak dari elemen awal. Jadi, elemen pertama berjarak 0 dari elemen awal. Jadi, itu sebabnya array mulai dari 0.
sumber
Itu karena
address
harus menunjuk ke kananelement
dalam array. Mari kita asumsikan array di bawah ini:Mari kita mempertimbangkan awal keberadaan alamat
12
dan ukuranelement
be4 bytes
.Jika itu tidak
zero-based
, secara teknis alamat elemen pertama kami diarray
akan16
yang salah karena lokasi itu adalah12
.sumber
Nama array adalah pointer konstan yang menunjuk ke alamat basis. Ketika Anda menggunakan arr [i] kompiler memanipulasi sebagai * (arr + i). Karena kisaran int adalah -128 hingga 127, kompiler berpikir bahwa -128 ke -1 adalah angka negatif dan 0 hingga 128 adalah angka positif. Jadi indeks array selalu dimulai dengan nol.
sumber
int
Diperlukan suatu jenis untuk mendukung setidaknya kisaran 16-bit, dan pada kebanyakan sistem dewasa ini mendukung 32-bit. Saya pikir logika Anda cacat, dan jawaban Anda benar-benar tidak meningkat pada jawaban lain yang sudah disediakan oleh orang lain. Saya sarankan menghapus ini.