Hanya pengamatan acak, tampaknya di StackOverflow.com, ada pertanyaan tentang apakah "++ i == i ++". Pertanyaan itu selalu ditanyakan, saya pikir saya melihatnya 6 atau 7 kali dalam 2 bulan terakhir.
Saya hanya ingin tahu mengapa pengembang C sangat tertarik pada itu? Konsep / pertanyaan yang sama ada untuk C # dan Java devs juga, tapi saya pikir saya hanya melihat satu pertanyaan terkait C #.
Apakah karena begitu banyak contoh menggunakan ++ i? Apakah karena ada beberapa buku atau tutorial populer? Apakah karena pengembang C hanya suka menjejalkan sebanyak mungkin ke dalam satu baris untuk 'efisiensi' / 'kinerja' dan oleh karena itu menemukan konstruksi 'aneh' menggunakan operator ++ lebih sering?
c
undefined-behavior
Michael Stum
sumber
sumber
++i == i++
, atau lebih umum tentang perbedaan makna antara++i
dani++
?Jawaban:
Saya menduga bahwa setidaknya sebagian darinya sedikit lebih sederhana: bahkan sekarang, kita melihat banyak pertanyaan seperti ini mulai sekitar awal tahun sekolah, dan mereka berangsur-angsur berkurang sepanjang tahun.
Dengan demikian, saya pikir wajar untuk menebak bahwa beberapa dari mereka hanyalah hasil dari kelas di mana guru berbicara setidaknya sedikit tentang hal itu, tetapi tidak menjelaskan maksudnya dengan baik (sesering mungkin tidak karena dia sendiri tidak terlalu mengerti mereka). Terutama berdasarkan pada orang-orang yang tampaknya mengajukan pertanyaan-pertanyaan ini, sedikit yang didasarkan pada pengkodean aktual.
sumber
Karena programmer C HARUS memahami urutan operasi. Pengembang C # tidak perlu menggunakan operator bitwise (&, |, ~) atau operator awalan karena kami biasanya lebih khawatir tentang hal-hal lain. Namun, apa yang tidak kita sadari oleh C # dev adalah bahwa kita harus tahu apa yang dilakukan oleh operator yang kita gunakan setiap hari dan bagaimana menggunakannya dengan benar. Sebagian besar dari kita hanya menghindari tempat-tempat di mana ini mungkin menjadi masalah.
Dari atas kepala Anda, apa output dari potongan ini?
Saya akan mengatakan sejumlah besar C # devs berpengalaman tidak tahu apa output ke Konsol.
sumber
if (myList[i++] == item)
. Pintar. Saya menemukannya mencari sumber pengecualian IndexOutOfRange ... Memang, sangat "pintar".++
digunakan pada pelampung sebelumnya, dan saya harus mengatakan itu tidak merasa sangat tepat. Apakah orang melakukannya? (Saya lebih suka+= 1
)Saya pikir ini sudah jelas. Dalam C #, untuk suatu
int i
,i++ == ++i
selalu salah sementara++i == i++
selalu benar, andal, dan semua orang yang tertarik dapat mengetahui ini dengan mudah hanya dengan mempelajari aturan C # (atau memang dengan hanya menjalankannya).Di C dan C ++, di sisi lain, itu hampir tidak terdefinisi karena tergantung pada kompiler, lingkungan eksekusi, platform, dll., Jadi itu adalah pertanyaan yang jauh lebih sulit untuk dijawab, jadi banyak orang bertanya.
sumber
Ini pertanyaan populer karena ini pertanyaan jebakan. Itu tidak terdefinisi .
Tautan di atas menuju ke FAQ tentang beranda Bjarnes Stroustrup, yang membahas pertanyaan ini secara khusus, dan menjelaskan mengapa konstruk ini tidak ditentukan. Apa yang dikatakannya adalah:
sumber
Kemungkinan besar karena dalam C, itu sangat penting jika Anda menulis
i++
atau++i
ketika Anda melakukan aritmatika pointer. Di sana, peningkatani
sebelum atau setelah operasi bisa menjadi sangat penting. Saya akan memberi Anda contoh tetapi terakhir kali saya menulis C adalah 10 tahun yang lalu ...Dalam C #, saya tidak pernah menemukan situasi yang mengharuskan saya untuk memikirkan
i++
atau++i
karena AFAIK, untuk loop sementara, itu tidak masalah.sumber
i++
dan++i
, tetapi menggabungkan mereka dalam ekspresi yang sama.Beberapa tahun yang lalu saya membaca bahwa operator ini dianggap berbahaya sehingga saya mencoba menggali lebih banyak informasi tentangnya. Jika stackoverflow sudah pada saat itu, saya akan bertanya di sana.
Sekarang karena beberapa orang yang bengkok menulis loop seperti
Bahkan sekarang, saya tidak terlalu yakin tentang apa yang akan / harus terjadi, tetapi cukup jelas bagi saya bahwa banyak ++ [var] pada baris yang sama meminta masalah.
sumber
x = ++j;
didefinisikan dengan baik dalam C. Di atas tidak terdefinisi karenaj
dimodifikasi dua kali tanpa titik urutan intervensi.Dua alasan.
Implementasi yang benar dari ++ i adalah untuk meningkatkan i dan kemudian mengembalikannya. Implementasi i ++ yang benar adalah untuk menyimpan nilai saat ini, meningkatkan i, dan mengembalikan nilai yang disimpan. Mengetahui hal ini tidak dilaksanakan karena sinonim adalah penting.
Pertanyaannya kemudian menjadi kapan kompiler menerapkannya saat mengevaluasi ekspresi, seperti kesetaraan.
Jika tes persamaan dilakukan terlebih dahulu, maka operator sebelum dan sesudah kenaikan, Anda harus menulis logika yang berbeda daripada jika sisi kiri (lhs) dan sisi kanan (rhs) dievaluasi terlebih dahulu, kemudian kesetaraan.
Ini semua tentang urutan operasi, dan pada gilirannya mempengaruhi kode yang ditulis. Dan, tidak terlalu mengejutkan, tidak semua bahasa sepakat.
Daftar tes dasar ini memungkinkan pengembang untuk menguji untuk melihat apakah asumsi mereka benar, serta apakah implementasi yang sebenarnya sesuai dengan spesifikasi bahasa.
Ini dapat memiliki semua jenis dampak ketika bekerja dengan pointer, loop, atau nilai yang dikembalikan.
sumber
++i
adalah menggunakan nilaii+1
dan pada titik waktu tertentu, mungkin sebelum atau setelah itu, tetapi sebelum titik urutan berikutnya, kenaikani
.Saya pikir ini adalah kejutan budaya.
Seperti yang telah ditunjukkan, perilaku ekspresi dalam C atau C ++ dapat tidak terdefinisi karena urutan eksekusi post-increments, dll tidak ditentukan secara ketat. Perilaku tidak terdefinisi cukup umum di C, dan tentu saja banyak yang diimpor ke C ++.
Untuk seseorang yang telah melakukan beberapa pemrograman dalam bahasa lain - seseorang yang telah mengambil gagasan bahwa bahasa pemrograman seharusnya tepat, dan bahwa komputer seharusnya melakukan apa yang diperintahkan untuk dilakukan ... yah, itu mengejutkan untuk temukan bahwa C sengaja disamarkan tentang beberapa hal.
sumber
++
dan--
operator tidak didasarkan pada PDP-11, yang tidak ada ketika operator tersebut diperkenalkan dalam bahasa pendahulunya C B. Lihat cm.bell-labs.com/who/dmr/chist.html , dan cari "peningkatan otomatis".Mungkin hanya bahwa pengembang C menggunakan kenaikan ++ lebih sering secara umum - melihat bagaimana C tidak memiliki "foreach" atau pernyataan serupa untuk beralih melalui array. Oh, dan tentu saja pointer aritmatika, seperti yang disebutkan sebelumnya!
sumber
Perbedaan antara kedua bagian: post dan preincrement bekerja seperti cara kedua bagian kode ini berfungsi di setiap bahasa. INI BUKAN BAHWA TERGANTUNG BAHASA !!!
Ini kenaikan pra. Sepotong kode ini pertama-tama akan meningkatkan nilai
i
sebelum mengirim nilai ke baris di mana ia digunakan.Ini adalah kenaikan pos. Potongan kode ini akan mengembalikan nilai
i
sebelum meningkatkan nilaii
pada baris di mana ia digunakan.Dalam contoh kecil lainnya:
Kompilasi kode ini dengan hasil pada codepad.
Ini ada hubungannya dengan implementasi internal operator yang kelebihan beban.
++i
meningkatkan nilai secara langsung (dan karena itu sedikit lebih cepat)i++
pertama membuat salinan yang dikembalikan ke tempat di mana diperlukan dan kemudian nilai asli darii
variabel tersebut bertambah satu.Saya harap ini jelas sekarang.
sumber
++i
tidak lebih cepat, dani++
tidak membuat salinan. Lebih lanjut,++i
berperilaku sedikit berbeda dalam C daripada di C ++, apalagi di antara bahasa lain.