Dalam C, apa perbedaan antara menggunakan ++i
dan i++
, dan yang harus digunakan dalam blok kenaikan for
loop?
c
for-loop
post-increment
pre-increment
The.Anti.9
sumber
sumber
Jawaban:
++i
akan menambah nilaii
, dan kemudian mengembalikan nilai yang bertambah.i++
akan menambah nilaii
, tetapi mengembalikan nilai asli yangi
dimiliki sebelum ditambahkan.Untuk satu
for
loop, keduanya berfungsi.++i
tampaknya lebih umum, mungkin karena itulah yang digunakan dalam K&R .Dalam kasus apapun, ikuti pedoman "lebih memilih
++i
lebihi++
" dan Anda tidak akan salah.Ada beberapa komentar mengenai efisiensi
++i
dani++
. Dalam kompiler non-siswa-proyek, tidak akan ada perbedaan kinerja. Anda dapat memverifikasi ini dengan melihat kode yang dihasilkan, yang akan identik.Pertanyaan efisiensi menarik ... inilah usaha saya pada jawaban: Apakah ada perbedaan kinerja antara i ++ dan ++ i di C?
Seperti yang dicatat oleh @ OnFreund , ini berbeda untuk objek C ++, karena
operator++()
merupakan fungsi dan kompiler tidak dapat mengoptimalisasi pembuatan objek sementara untuk menyimpan nilai perantara.sumber
for(int i=0; i<10; i++){ print i; }
bukankah ini berbeda darifor(int i=0; i<10; ++i){ print i; }
pemahaman saya adalah bahwa beberapa bahasa akan memberikan hasil yang berbeda tergantung pada yang Anda gunakan.i++
karena itu dalam bentuk "operan-operator", ala penugasan "operand-operator-nilai". Dengan kata lain, operan target ada di sisi kiri ekspresi, sama seperti dalam pernyataan penugasan.i++
danprint i
dalam pernyataan yang berbeda, tetapi karenai++;
dani<10
sedang. Komentar @ jonnyflash bukan tidak masuk akal. Misalkan Anda punyafor(int i=0; i++<10){ print i; }
danfor(int i=0; ++i<10){ print i; }
. Ini akan beroperasi secara berbeda dengan cara yang dijelaskan oleh @johnnyflash dalam komentar pertama.i ++ dikenal sebagai Post Increment sedangkan ++ i disebut Pre Increment.
i++
i++
adalah kenaikan pasca karena kenaikani
nilainya sebesar 1 setelah operasi selesai.Mari kita lihat contoh berikut:
Di sini nilai
j = 1
tetapii = 2
. Di sini nilaii
akan ditugaskanj
terlebih dahulu kemudiani
akan bertambah.++i
++i
adalah pra kenaikan karenai
nilainya bertambah 1 sebelum operasi. Itu berartij = i;
akan mengeksekusi setelahi++
.Mari kita lihat contoh berikut:
Di sini nilai
j = 2
tetapii = 2
. Di sini nilaii
akan ditugaskanj
setelahi
kenaikani
. Demikian pula++i
akan dieksekusi sebelumnyaj=i;
.Untuk pertanyaan Anda, yang mana yang harus digunakan dalam blok incrementation dari for for? jawabannya adalah, Anda dapat menggunakan salah satunya .. tidak masalah. Ini akan mengeksekusi for for loop no yang sama. kali.
Dan
Kedua loop akan menghasilkan output yang sama. yaitu
0 1 2 3 4
.Itu hanya masalah di mana Anda menggunakannya.
Dalam hal ini output akan menjadi
1 2 3 4 5
.sumber
Tolong jangan khawatir tentang "efisiensi" (kecepatan, sungguh) yang mana lebih cepat. Kami memiliki kompiler hari ini yang mengurus hal-hal ini. Gunakan mana pun yang masuk akal untuk digunakan, berdasarkan mana yang lebih jelas menunjukkan niat Anda.
sumber
operator++(int)
(versi postfix) kode harus membuat sementara yang akan dikembalikan. Apakah Anda yakin bahwa kompiler selalu dapat mengoptimalkannya?++i
menambah nilainya, lalu mengembalikannya.i++
mengembalikan nilai, dan kemudian menambahkannya.Ini perbedaan yang halus.
Untuk for for, gunakan
++i
, karena sedikit lebih cepat.i++
akan membuat salinan tambahan yang baru saja dibuang.sumber
i++
: Dalam skenario ini pertama-tama nilainya diberikan dan kemudian kenaikan terjadi.++i
: Dalam skenario ini, pertama kenaikan dilakukan dan kemudian nilai diberikanDi bawah ini adalah visualisasi gambar dan juga di sini adalah video praktis yang bagus yang menunjukkan hal yang sama.
sumber
Alasannya
++i
bisa sedikit lebih cepat daripadai++
yangi++
dapat memerlukan salinan lokal dari nilai i sebelum bertambah, sementara++i
tidak pernah melakukannya. Dalam beberapa kasus, beberapa kompiler akan mengoptimalkannya jika memungkinkan ... tetapi itu tidak selalu memungkinkan, dan tidak semua kompiler melakukan ini.Saya mencoba untuk tidak terlalu mengandalkan optimisasi kompiler, jadi saya akan mengikuti saran Ryan Fox: ketika saya bisa menggunakan keduanya, saya gunakan
++i
.sumber
i
selain dari nilai 1 ketika Anda menulis pernyataan1;
.Hasil efektif menggunakan salah satu dalam satu lingkaran adalah identik. Dengan kata lain, loop akan melakukan hal yang persis sama di kedua instance.
Dalam hal efisiensi, mungkin ada penalti yang terlibat dengan memilih i ++ lebih dari ++ i. Dalam hal spesifikasi bahasa, menggunakan operator pasca kenaikan harus membuat salinan tambahan dari nilai yang digunakan operator. Ini bisa menjadi sumber operasi tambahan.
Namun, Anda harus mempertimbangkan dua masalah utama dengan logika sebelumnya.
Kompiler modern sangat bagus. Semua kompiler yang baik cukup pintar untuk menyadari bahwa ia melihat peningkatan bilangan bulat dalam for-loop, dan itu akan mengoptimalkan kedua metode ke kode efisien yang sama. Jika menggunakan post-increment lebih dari pre-increment sebenarnya menyebabkan program Anda berjalan lebih lambat, maka Anda menggunakan kompilator yang mengerikan .
Dalam hal kompleksitas waktu operasional, kedua metode (bahkan jika salinan benar-benar dilakukan) adalah setara. Jumlah instruksi yang dilakukan di dalam loop harus mendominasi jumlah operasi dalam operasi kenaikan secara signifikan. Oleh karena itu, dalam setiap loop dengan ukuran signifikan, penalti metode kenaikan akan dibayangi secara besar-besaran oleh eksekusi loop body. Dengan kata lain, Anda jauh lebih baik khawatir tentang mengoptimalkan kode dalam loop daripada kenaikan.
Menurut pendapat saya, seluruh masalah hanya bermuara pada preferensi gaya. Jika Anda merasa pra-kenaikan lebih mudah dibaca, maka gunakan. Secara pribadi, saya lebih suka post-incrment, tapi itu mungkin karena itu yang saya pelajari sebelum saya tahu apa-apa tentang optimasi.
Ini adalah contoh klasik dari pengoptimalan prematur, dan masalah seperti ini berpotensi mengalihkan perhatian kita dari masalah serius dalam desain. Namun, ini masih merupakan pertanyaan yang bagus untuk ditanyakan, karena tidak ada keseragaman dalam penggunaan atau konsensus dalam "praktik terbaik".
sumber
Mereka berdua menambah jumlahnya.
++i
setara dengani = i + 1
.i++
dan++i
sangat mirip tetapi tidak persis sama. Keduanya menambah angka, tetapi++i
menambah angka sebelum ekspresi saat ini dievaluasi, sedangkani++
menambah angka setelah ekspresi dievaluasi.Contoh:
sumber
++i
(Prefix operasi): Peningkatan- dan kemudian memberikan nilai(misalnya):
int i = 5
,int b = ++i
Dalam hal ini, 6 ditugaskan untuk b pertama dan kemudian bertahap ke 7 dan seterusnya.i++
(Postfix operasi): Penerima dan kemudian menambahkan nilai(misalnya):
int i = 5
,int b = i++
Dalam hal ini, 5 ditugaskan untuk b pertama dan kemudian bertahap ke 6 dan seterusnya.Incase of for loop:
i++
sebagian besar digunakan karena, biasanya kami menggunakan nilai awali
sebelum menambahkan untuk loop. Tetapi tergantung pada logika program Anda, itu mungkin berbeda.sumber
++i
: adalah pra-kenaikan yang lain adalah pasca-kenaikan.i++
: dapatkan elemen dan kemudian menambahkannya.++i
: increments i dan kemudian mengembalikan elemen.Contoh:
Keluaran:
sumber
Saya berasumsi Anda memahami perbedaan dalam semantik sekarang (meskipun jujur saya bertanya-tanya mengapa orang bertanya 'apa arti operator X' pada stack overflow daripada membaca, Anda tahu, buku atau tutorial web atau sesuatu.
Tapi bagaimanapun, sejauh mana yang digunakan, abaikan pertanyaan kinerja, yang sepertinya tidak penting bahkan di C ++. Ini adalah prinsip yang harus Anda gunakan ketika memutuskan mana yang akan digunakan:
Katakan apa yang Anda maksud dalam kode.
Jika Anda tidak membutuhkan nilai sebelum kenaikan dalam pernyataan Anda, jangan gunakan bentuk operator itu. Ini masalah kecil, tetapi kecuali jika Anda bekerja dengan panduan gaya yang melarang satu versi untuk mendukung versi yang lain sama sekali (alias panduan gaya berkepala dingin), Anda harus menggunakan formulir yang paling tepat mengungkapkan apa yang Anda coba lakukan.
QED, gunakan versi pra-kenaikan:
sumber
Perbedaannya dapat dipahami oleh kode C ++ sederhana di bawah ini:
sumber
sumber
i ++ dan ++ i
Kode kecil ini dapat membantu memvisualisasikan perbedaan dari sudut yang berbeda dari jawaban yang sudah diposting:
Hasilnya adalah:
Perhatikan situasi sebelum dan sesudah.
untuk loop
Adapun yang salah satunya harus digunakan dalam blok incrementation dari for for, saya pikir yang terbaik yang bisa kita lakukan untuk mengambil keputusan adalah menggunakan contoh yang baik:
Hasilnya adalah:
Saya tidak tahu tentang Anda, tetapi saya tidak melihat perbedaan dalam penggunaannya, setidaknya dalam perulangan for.
sumber
Fragmen kode C berikut menggambarkan perbedaan antara operator kenaikan dan penurunan pra dan pasca:
Operator tambahan:
sumber
Pre-crement berarti kenaikan pada baris yang sama. Penambahan pasca berarti peningkatan setelah garis dieksekusi.
Ketika datang dengan OR, DAN operator, itu menjadi lebih menarik.
Dalam Array
Dalam C ++ post / pre-increment variabel pointer
sumber
Segera:
++i
dani++
berfungsi sama jika Anda tidak menuliskannya dalam suatu fungsi. Jika Anda menggunakan sesuatu sepertifunction(i++)
ataufunction(++i)
Anda dapat melihat perbedaannya.function(++i)
mengatakan kenaikan pertama i dengan 1, setelah itu masukkan inii
ke dalam fungsi dengan nilai baru.function(i++)
mengatakan dimasukkan pertamai
ke dalam fungsi setelah kenaikani
sebesar 1.sumber
int j = ++i;
danint k = i++;
bahkan ketika tidak ada panggilan fungsi yang terlibat.Satu-satunya perbedaan adalah urutan operasi antara kenaikan variabel dan nilai yang dikembalikan operator.
Kode ini dan hasilnya menjelaskan perbedaannya:
Output adalah:
Jadi pada dasarnya
++i
mengembalikan nilai setelah itu bertambah, sementara++i
mengembalikan nilai sebelum itu bertambah. Pada akhirnya, dalam kedua kasus tersebuti
akan nilainya bertambah.Contoh lain:
Keluaran:
Seringkali tidak ada perbedaan
Perbedaannya jelas ketika nilai yang dikembalikan ditugaskan ke variabel lain atau ketika kenaikan dilakukan dalam penggabungan dengan operasi lain di mana operasi diutamakan diterapkan (
i++*2
berbeda dari++i*2
, tetapi(i++)*2
dan(++i)*2
mengembalikan nilai yang sama) dalam banyak kasus mereka dipertukarkan. Contoh klasik adalah sintaks for loop:memiliki efek yang sama
Aturan untuk diingat
Untuk tidak membuat kebingungan antara kedua operator saya mengadopsi aturan ini:
Kaitkan posisi operator
++
sehubungan dengan variabeli
ke urutan++
operasi sehubungan dengan penugasanDiucapkan dengan kata lain:
++
sebelumi
berarti penambahan harus dilakukan sebelum penugasan;++
setelahi
sarana tambahan harus dilakukan setelah penugasan:sumber
Anda dapat menganggap konversi internal itu sebagai beberapa pernyataan ;
Anda bisa menganggapnya sebagai,
Anda bisa menganggapnya sebagai,
sumber
a = i ++ berarti a berisi nilai i saat ini a = ++ i berarti a berisi nilai i yang bertambah
sumber
a = i++;
berarti nilai yang disimpan dalama
akan menjadi nilaii
sebelum kenaikan, tetapi 'tanpa penambahan' menyiratkan bahwai
tidak bertambah, yang sama sekali salah -i
bertambah, tetapi nilai ekspresi adalah nilai sebelum kenaikan.Berikut adalah contoh untuk memahami perbedaannya
keluaran:
10 12/11 11
(tergantung pada urutan evaluasi argumen terhadapprintf
fungsi, yang bervariasi antar kompiler dan arsitektur)Penjelasan:
i++
->i
dicetak, lalu ditambahkan. (Mencetak 10, tetapii
akan menjadi 11)++i
->i
peningkatan nilai dan mencetak nilai. (Mencetak 12, dan nilaii
juga 12)sumber
i++
dan++i