Saat ini saya mempelajari C ++ dan saya telah mempelajari tentang inkrementasi beberapa waktu yang lalu. Saya tahu bahwa Anda dapat menggunakan "++ x" untuk membuat penambahan sebelum dan "x ++" untuk melakukannya setelahnya.
Namun, saya benar-benar tidak tahu kapan harus menggunakan salah satu dari keduanya ... Saya tidak pernah benar-benar menggunakan "++ x" dan sejauh ini semuanya selalu berfungsi dengan baik - jadi, kapan saya harus menggunakannya?
Contoh: Dalam perulangan for, kapan lebih baik menggunakan "++ x"?
Selain itu, dapatkah seseorang menjelaskan dengan tepat cara kerja incrementation (atau decrementation) yang berbeda? Aku akan sangat menghargainya.
sumber
x++
adalah nilai r dengan nilaix
sebelum kenaikan,x++
adalah nilai l dengan nilaix
setelah kenaikan. Tidak ada ekspresi yang menjamin saat nilai inkrementasi aktual disimpan kembali ke x, hanya dijamin bahwa itu terjadi sebelum titik urutan berikutnya. 'setelah memproses pernyataan saat ini' tidak sepenuhnya akurat karena beberapa ekspresi memiliki titik urutan dan beberapa pernyataan adalah pernyataan gabungan.Scott Meyers memberitahu Anda untuk memilih prefiks kecuali pada saat-saat di mana logika akan menentukan bahwa postfix tepat.
"C ++ Lebih Efektif" item # 6 - itu otoritas yang cukup bagi saya.
Bagi mereka yang tidak memiliki buku tersebut, berikut adalah kutipan terkait. Dari halaman 32:
Dan di halaman 34:
sumber
i++
atau++i
, kode yang dihasilkan sama.++x
danx++
benar-benar penting, itu jauh lebih penting bahwa Anda benar-benar menggunakan compiler yang benar-benar dan benar dapat mengoptimalkan baik versi tidak peduli apa konteks. "Karena saya menggunakan palu tua yang jelek ini, saya hanya dapat memasukkan paku pada sudut 43,7 derajat" adalah argumen yang buruk untuk membangun rumah dengan memasukkan paku hanya pada 43,7 derajat. Gunakan alat yang lebih baik.Dari cppreference saat menambahkan iterator:
Iter operator++(int) { Iter tmp(*this); // store the old value in a temporary object ++*this; // call pre-increment return tmp; // return the old value }
Pre-increment tidak menghasilkan objek sementara. Ini dapat membuat perbedaan yang signifikan jika objek Anda mahal untuk dibuat.
sumber
Saya hanya ingin memperhatikan bahwa kode genetika salah sama jika Anda menggunakan inkrementasi pra / posting di mana semantik (dari pra / posting) tidak masalah.
contoh:
pre.cpp:
#include <iostream> int main() { int i = 13; i++; for (; i < 42; i++) { std::cout << i << std::endl; } }
post.cpp:
#include <iostream> int main() { int i = 13; ++i; for (; i < 42; ++i) { std::cout << i << std::endl; } }
_
$> g++ -S pre.cpp $> g++ -S post.cpp $> diff pre.s post.s 1c1 < .file "pre.cpp" --- > .file "post.cpp"
sumber
std::map::iterator
? Tentu saja ada dua operator yang berbeda, tetapi saya penasaran apakah kompiler akan mengoptimalkan postfix ke prefix jika hasilnya tidak digunakan. Saya rasa itu tidak diperbolehkan - mengingat versi postfix dapat mengandung efek samping.Hal terpenting yang perlu diingat, imo, adalah bahwa x ++ perlu mengembalikan nilai sebelum kenaikan benar-benar terjadi - oleh karena itu, ia harus membuat salinan sementara dari objek tersebut (kenaikan awal). Ini kurang efisien daripada ++ x, yang ditambahkan di tempat dan dikembalikan.
Hal lain yang perlu disebutkan, adalah bahwa sebagian besar kompiler akan dapat mengoptimalkan hal-hal yang tidak perlu jika memungkinkan, misalnya kedua opsi akan mengarah ke kode yang sama di sini:
for (int i(0);i<10;++i) for (int i(0);i<10;i++)
sumber
Saya setuju dengan @BeowulfOF, meskipun untuk kejelasan, saya akan selalu menganjurkan pemisahan pernyataan sehingga logikanya benar-benar jelas, yaitu:
atau
Jadi jawaban saya adalah jika Anda menulis kode yang jelas maka ini jarang menjadi masalah (dan jika itu penting maka kode Anda mungkin tidak cukup jelas).
sumber
Hanya ingin menekankan kembali bahwa ++ x diharapkan lebih cepat dari x ++, (terutama jika x adalah objek dari beberapa tipe arbitrer), jadi kecuali diperlukan untuk alasan logis, ++ x harus digunakan.
sumber
Anda menjelaskan perbedaannya dengan benar. Itu hanya tergantung pada apakah Anda ingin x meningkat sebelum setiap proses melalui loop, atau setelah itu. Itu tergantung pada logika program Anda, apa yang sesuai.
Perbedaan penting saat berurusan dengan STL-Iterator (yang juga mengimplementasikan operator ini) adalah, bahwa ++ membuat salinan objek yang ditunjuk iterator, lalu menambah, dan kemudian mengembalikan salinannya. ++ itu di sisi lain melakukan penambahan terlebih dahulu dan kemudian mengembalikan referensi ke objek yang sekarang ditunjuk oleh iterator. Ini sebagian besar hanya relevan ketika setiap bit kinerja diperhitungkan atau saat Anda menerapkan iterator STL Anda sendiri.
Edit: memperbaiki campuran awalan dan notasi sufiks
sumber
Contoh 1:
Ketika beberapa nilai di-cascade dengan << menggunakan cout maka perhitungan (jika ada) dilakukan dari kanan-ke-kiri tetapi pencetakan berlangsung dari kiri-ke-kanan misalnya, (jika val jika awalnya 10)
cout<< ++val<<" "<< val++<<" "<< val;
akan menghasilkan
12 10 10
Contoh 2:
Dalam Turbo C ++, jika beberapa kemunculan ++ atau (dalam bentuk apapun) ditemukan dalam sebuah ekspresi, maka pertama-tama semua bentuk prefiks dihitung kemudian ekspresi dievaluasi dan terakhir bentuk postfix dihitung misalnya,
int a=10,b; b=a++ + ++a + ++a + a; cout<<b<<a<<endl;
Outputnya di Turbo C ++ akan
48 13
Sedangkan keluarannya dalam kompiler modern adalah (karena mereka mengikuti aturan dengan ketat)
45 13
ekspresi tersebut bervariasi dari kompilator ke kompilator.
sumber
Memahami sintaks bahasa penting saat mempertimbangkan kejelasan kode. Pertimbangkan untuk menyalin string karakter, misalnya dengan kenaikan pasca:
char a[256] = "Hello world!"; char b[256]; int i = 0; do { b[i] = a[i]; } while (a[i++]);
Kami ingin loop dieksekusi melalui pertemuan dengan karakter nol (yang menguji false) di akhir string. Itu membutuhkan pengujian nilai pra-kenaikan dan juga menaikkan indeks. Tetapi tidak harus dalam urutan itu - cara untuk mengkodekan ini dengan kenaikan awal adalah:
int i = -1; do { ++i; b[i] = a[i]; } while (a[i]);
Ini masalah selera yang lebih jelas dan jika mesin memiliki beberapa register, keduanya harus memiliki waktu eksekusi yang sama, bahkan jika [i] adalah fungsi yang mahal atau memiliki efek samping. Perbedaan yang signifikan mungkin adalah nilai keluar dari indeks.
sumber