Saya pikir ada sesuatu yang terlewatkan oleh jawaban lain.
Ya, p[i]
secara definisi setara dengan *(p+i)
, yang (karena penambahan komutatif) setara dengan *(i+p)
, yang (sekali lagi, menurut definisi []
operator) setara dengan i[p]
.
(Dan dalam array[i]
, nama array secara implisit dikonversi menjadi pointer ke elemen pertama array.)
Tetapi komutatifitas penambahan tidak begitu jelas dalam kasus ini.
Ketika kedua operan adalah dari jenis yang sama, atau bahkan dari jenis numerik yang berbeda yang dipromosikan ke jenis umum, komutatif masuk akal: x + y == y + x
.
Tetapi dalam kasus ini kita berbicara secara spesifik tentang pointer aritmatika, di mana satu operan adalah pointer dan yang lainnya adalah integer. (Integer + integer adalah operasi yang berbeda, dan pointer + pointer tidak masuk akal.)
Deskripsi standar C +
operator ( N1570 6.5.6) mengatakan:
Sebagai tambahan, kedua operan harus memiliki tipe aritmatika, atau satu operan harus menjadi pointer ke tipe objek lengkap dan yang lainnya harus memiliki tipe integer.
Itu bisa dengan mudah dikatakan:
Sebagai tambahan, kedua operan harus memiliki tipe aritmatika, atau
operan kiri harus menjadi pointer ke tipe objek lengkap dan operan kanan
harus memiliki tipe integer.
dalam hal ini keduanya i + p
dan i[p]
akan ilegal.
Dalam istilah C ++, kami benar-benar memiliki dua set +
operator kelebihan beban , yang secara longgar dapat digambarkan sebagai:
pointer operator+(pointer p, integer i);
dan
pointer operator+(integer i, pointer p);
dimana hanya yang pertama yang benar-benar diperlukan.
Jadi mengapa demikian?
C ++ mewarisi definisi ini dari C, yang mendapatkannya dari B (komutatifitas pengindeksan array secara eksplisit disebutkan dalam referensi pengguna 1972 ke B ), yang mendapatkannya dari BCPL (manual bertanggal 1967), yang mungkin mendapatkannya dari gen bahasa sebelumnya (CPL? Algol?).
Jadi gagasan bahwa pengindeksan array didefinisikan dalam hal penambahan, dan penambahan itu, bahkan penunjuk dan bilangan bulat, adalah komutatif, kembali beberapa dekade, ke bahasa leluhur C.
Bahasa-bahasa itu diketik kurang kuat daripada C modern. Secara khusus, perbedaan antara pointer dan integer sering diabaikan. (Pemrogram C awal kadang-kadang menggunakan pointer sebagai bilangan bulat yang tidak ditandatangani, sebelum unsigned
kata kunci ditambahkan ke bahasa.) Jadi ide membuat penambahan non-komutatif karena operan dari tipe yang berbeda mungkin tidak akan terjadi pada perancang bahasa tersebut. Jika pengguna ingin menambahkan dua "hal", apakah "hal" itu adalah bilangan bulat, pointer, atau sesuatu yang lain, itu tidak sesuai dengan bahasa untuk mencegahnya.
Dan selama bertahun-tahun, setiap perubahan pada aturan itu akan merusak kode yang ada (meskipun standar ANSI C 1989 mungkin merupakan peluang yang baik).
Mengubah C dan / atau C ++ untuk mengharuskan meletakkan pointer di sebelah kiri dan integer di sebelah kanan dapat merusak beberapa kode yang ada, tetapi tidak akan ada kehilangan kekuatan ekspresif nyata.
Jadi sekarang kita memiliki arr[3]
dan 3[arr]
memaknai hal yang persis sama, meskipun bentuk yang terakhir seharusnya tidak pernah muncul di luar IOCCC .