Saya baru saja membaca beberapa kode dan menemukan bahwa orang tersebut menggunakan arr[-2]
untuk mengakses elemen ke-2 sebelum arr
, seperti:
|a|b|c|d|e|f|g|
^------------ arr[0]
^---------- arr[1]
^---------------- arr[-2]
Apa itu diperbolehkan?
Saya tahu itu arr[x]
sama dengan *(arr + x)
. Begitu arr[-2]
juga *(arr - 2)
, yang tampaknya oke. Bagaimana menurut anda?
somearray-2
yang tidak ditentukan kecuali hasilnya berada dalam kisaran dari awalsomearray
hingga 1 setelah akhirnya.[]
itu direferensikan sebagai gula sintaks untuk aritmatika penunjuk. Cara favorit untuk membingungkan pemula adalah dengan menulis1[arr]
- alih-aliharr[1]
- dan melihat mereka menebak-nebak apa maksudnya.((E1)+(E2))
akan menjadi pointer (64-bit) dengan nilai yang diharapkan.Ini hanya valid jika
arr
pointer yang menunjuk ke elemen kedua dalam array atau elemen yang lebih baru. Jika tidak, ini tidak valid, karena Anda akan mengakses memori di luar batas array. Jadi, misalnya, ini salah:Tapi ini tidak masalah:
Namun, tidak biasa menggunakan subskrip negatif.
sumber
int arr[10];
merupakan bagian dari struktur dengan elemen lain sebelumnya,arr[-2]
berpotensi terdefinisi dengan baik, dan Anda dapat menentukan apakah itu didasarkan padaoffsetof
, dll.If one is sure that the elements exist, it is also possible to index backwards in an array; p[-1], p[-2], and so on are syntactically legal, and refer to the elements that immediately precede p[0]. Of course, it is illegal to refer to objects that are not within the array bounds.
Tetap saja, teladan Anda lebih baik dalam membantu saya memahaminya. Terima kasih!Kedengarannya bagus untukku. Akan menjadi kasus yang jarang terjadi bahwa Anda membutuhkannya secara sah.
sumber
Apa yang mungkin adalah yang
arr
menunjuk ke tengah array, sehinggaarr[-2]
menunjuk ke sesuatu dalam array asli tanpa keluar batas.sumber
Saya tidak yakin seberapa andal ini, tetapi saya baru saja membaca peringatan berikut tentang indeks array negatif pada sistem 64-bit (LP64 mungkin): http://www.devx.com/tips/Tip/41349
Penulis tampaknya mengatakan bahwa indeks larik int 32 bit dengan pengalamatan 64 bit dapat menghasilkan kalkulasi alamat yang buruk kecuali indeks larik secara eksplisit dipromosikan ke 64 bit (misalnya melalui ptrdiff_t cast). Saya benar-benar telah melihat bug dari sifatnya dengan versi PowerPC dari gcc 4.1.0, tetapi saya tidak tahu apakah itu bug kompiler (yaitu harus bekerja sesuai dengan standar C99) atau perilaku yang benar (yaitu indeks membutuhkan cast ke 64 bit untuk perilaku yang benar)?
sumber
Saya tahu pertanyaannya telah terjawab, tetapi saya tidak dapat menahan diri untuk tidak membagikan penjelasan ini.
Saya ingat Prinsip desain Kompiler, Mari kita asumsikan a adalah larik int dan ukuran int adalah 2, & Alamat dasar untuk a adalah 1000.
Bagaimana
a[5]
bekerja ->Penjelasan ini juga menjadi alasan mengapa indeks negatif dalam array bekerja di C.
yaitu jika saya mengaksesnya
a[-5]
akan memberi sayaIni akan mengembalikan saya objek di lokasi 990. Dengan logika ini kita dapat mengakses indeks negatif di Array di C.
sumber
Tentang mengapa seseorang ingin menggunakan indeks negatif, saya telah menggunakannya dalam dua konteks:
Memiliki tabel bilangan kombinatorial yang memberi tahu Anda sisir [1] [- 1] = 0; Anda selalu dapat memeriksa indeks sebelum mengakses tabel, tetapi dengan cara ini kode terlihat lebih bersih dan dijalankan lebih cepat.
Menempatkan centinel di awal tabel. Misalnya, Anda ingin menggunakan sesuatu seperti
tetapi kemudian Anda juga harus memeriksa bahwa
i
itu positif.Solusi: membuatnya sehingga
a[-1]
adalah-DBLE_MAX
, sehinggax<a[-1]
akan selalu palsu.sumber
sumber