Dalam C, apa perbedaan antara menggunakan ++i
dan i++
, dan yang harus digunakan dalam blok kenaikan for
loop?
Dalam C, apa perbedaan antara menggunakan ++i
dan i++
, dan yang harus digunakan dalam blok kenaikan for
loop?
Jawaban:
++i
akan menambah nilai i
, dan kemudian mengembalikan nilai yang bertambah.
i = 1;
j = ++i;
(i is 2, j is 2)
i++
akan menambah nilai i
, tetapi mengembalikan nilai asli yang i
dimiliki sebelum ditambahkan.
i = 1;
j = i++;
(i is 2, j is 1)
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
lebih i++
" dan Anda tidak akan salah.
Ada beberapa komentar mengenai efisiensi ++i
dan i++
. 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.
for(int i=0; i<10; i++){ print i; }
bukankah ini berbeda dari for(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++
dan print i
dalam pernyataan yang berbeda, tetapi karena i++;
dan i<10
sedang. Komentar @ jonnyflash bukan tidak masuk akal. Misalkan Anda punya for(int i=0; i++<10){ print i; }
dan for(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 kenaikan i
nilainya sebesar 1 setelah operasi selesai.
Mari kita lihat contoh berikut:
int i = 1, j;
j = i++;
Di sini nilai j = 1
tetapi i = 2
. Di sini nilai i
akan ditugaskan j
terlebih dahulu kemudian i
akan bertambah.
++i
++i
adalah pra kenaikan karena i
nilainya bertambah 1 sebelum operasi. Itu berarti j = i;
akan mengeksekusi setelah i++
.
Mari kita lihat contoh berikut:
int i = 1, j;
j = ++i;
Di sini nilai j = 2
tetapi i = 2
. Di sini nilai i
akan ditugaskan j
setelah i
kenaikan i
. Demikian pula ++i
akan dieksekusi sebelumnya j=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.
for(i=0; i<5; i++)
printf("%d ",i);
Dan
for(i=0; i<5; ++i)
printf("%d ",i);
Kedua loop akan menghasilkan output yang sama. yaitu 0 1 2 3 4
.
Itu hanya masalah di mana Anda menggunakannya.
for(i = 0; i<5;)
printf("%d ",++i);
Dalam hal ini output akan menjadi 1 2 3 4 5
.
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.
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.
i++
: Dalam skenario ini pertama-tama nilainya diberikan dan kemudian kenaikan terjadi.
++i
: Dalam skenario ini, pertama kenaikan dilakukan dan kemudian nilai diberikan
Di bawah ini adalah visualisasi gambar dan juga di sini adalah video praktis yang bagus yang menunjukkan hal yang sama.
Alasannya ++i
bisa sedikit lebih cepat daripada i++
yang i++
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
.
i
selain dari nilai 1 ketika Anda menulis pernyataan 1;
.
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".
Mereka berdua menambah jumlahnya. ++i
setara dengan i = i + 1
.
i++
dan ++i
sangat mirip tetapi tidak persis sama. Keduanya menambah angka, tetapi ++i
menambah angka sebelum ekspresi saat ini dievaluasi, sedangkan i++
menambah angka setelah ekspresi dievaluasi.
Contoh:
int i = 1;
int x = i++; //x is 1, i is 2
int y = ++i; //y is 3, i is 3
++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 awal i
sebelum menambahkan untuk loop. Tetapi tergantung pada logika program Anda, itu mungkin berbeda.
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:
for (int i = 0; i != X; ++i) ...
Perbedaannya dapat dipahami oleh kode C ++ sederhana di bawah ini:
int i, j, k, l;
i = 1; //initialize int i with 1
j = i+1; //add 1 with i and set that as the value of j. i is still 1
k = i++; //k gets the current value of i, after that i is incremented. So here i is 2, but k is 1
l = ++i; // i is incremented first and then returned. So the value of i is 3 and so does l.
cout << i << ' ' << j << ' ' << k << ' '<< l << endl;
return 0;
Perbedaan utama adalah
- i ++ Post ( Setelah Bertambah ) dan
++ i Pra ( Sebelum Bertambah )
- memposting jika
i =1
loop bertambah suka1,2,3,4,n
- pre jika
i =1
loop bertambah suka2,3,4,5,n
Kode kecil ini dapat membantu memvisualisasikan perbedaan dari sudut yang berbeda dari jawaban yang sudah diposting:
int i = 10, j = 10;
printf ("i is %i \n", i);
printf ("i++ is %i \n", i++);
printf ("i is %i \n\n", i);
printf ("j is %i \n", j);
printf ("++j is %i \n", ++j);
printf ("j is %i \n", j);
Hasilnya adalah:
//Remember that the values are i = 10, and j = 10
i is 10
i++ is 10 //Assigns (print out), then increments
i is 11
j is 10
++j is 11 //Increments, then assigns (print out)
j is 11
Perhatikan situasi sebelum dan sesudah.
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:
int i, j;
for (i = 0; i <= 3; i++)
printf (" > iteration #%i", i);
printf ("\n");
for (j = 0; j <= 3; ++j)
printf (" > iteration #%i", j);
Hasilnya adalah:
> iteration #0 > iteration #1 > iteration #2 > iteration #3
> iteration #0 > iteration #1 > iteration #2 > iteration #3
Saya tidak tahu tentang Anda, tetapi saya tidak melihat perbedaan dalam penggunaannya, setidaknya dalam perulangan for.
Fragmen kode C berikut menggambarkan perbedaan antara operator kenaikan dan penurunan pra dan pasca:
int i;
int j;
Operator tambahan:
i = 1;
j = ++i; // i is now 2, j is also 2
j = i++; // i is now 3, j is 2
Pre-crement berarti kenaikan pada baris yang sama. Penambahan pasca berarti peningkatan setelah garis dieksekusi.
int j=0;
System.out.println(j); //0
System.out.println(j++); //0. post-increment. It means after this line executes j increments.
int k=0;
System.out.println(k); //0
System.out.println(++k); //1. pre increment. It means it increments first and then the line executes
Ketika datang dengan OR, DAN operator, itu menjadi lebih menarik.
int m=0;
if((m == 0 || m++ == 0) && (m++ == 1)) { //false
/* in OR condition if first line is already true then compiler doesn't check the rest. It is technique of compiler optimization */
System.out.println("post-increment "+m);
}
int n=0;
if((n == 0 || n++ == 0) && (++n == 1)) { //true
System.out.println("pre-increment "+n); //1
}
Dalam Array
System.out.println("In Array");
int[] a = { 55, 11, 15, 20, 25 } ;
int ii, jj, kk = 1, mm;
ii = ++a[1]; // ii = 12. a[1] = a[1] + 1
System.out.println(a[1]); //12
jj = a[1]++; //12
System.out.println(a[1]); //a[1] = 13
mm = a[1];//13
System.out.printf ( "\n%d %d %d\n", ii, jj, mm ) ; //12, 12, 13
for (int val: a) {
System.out.print(" " +val); //55, 13, 15, 20, 25
}
Dalam C ++ post / pre-increment variabel pointer
#include <iostream>
using namespace std;
int main() {
int x=10;
int* p = &x;
std::cout<<"address = "<<p<<"\n"; //prints address of x
std::cout<<"address = "<<p<<"\n"; //prints (address of x) + sizeof(int)
std::cout<<"address = "<<&x<<"\n"; //prints address of x
std::cout<<"address = "<<++&x<<"\n"; //error. reference can't re-assign because it is fixed (immutable)
}
Segera:
++i
dan i++
berfungsi sama jika Anda tidak menuliskannya dalam suatu fungsi. Jika Anda menggunakan sesuatu seperti function(i++)
atau function(++i)
Anda dapat melihat perbedaannya.
function(++i)
mengatakan kenaikan pertama i dengan 1, setelah itu masukkan ini i
ke dalam fungsi dengan nilai baru.
function(i++)
mengatakan dimasukkan pertama i
ke dalam fungsi setelah kenaikan i
sebesar 1.
int i=4;
printf("%d\n",pow(++i,2));//it prints 25 and i is 5 now
i=4;
printf("%d",pow(i++,2));//it prints 16 i is 5 now
int j = ++i;
dan int 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:
#include<stdio.h>
int main(int argc, char* argv[])
{
unsigned int i=0, a;
a = i++;
printf("i before: %d; value returned by i++: %d, i after: %d\n", i, a, i);
i=0;
a = ++i;
printf("i before: %d; value returned by ++i: %d, i after: %d\n", i, a, i);
}
Output adalah:
i before: 1; value returned by i++: 0, i after: 1
i before: 1; value returned by ++i: 1, i after: 1
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:
#include<stdio.h>
int main ()
int i=0;
int a = i++*2;
printf("i=0, i++*2=%d\n", a);
i=0;
a = ++i * 2;
printf("i=0, ++i*2=%d\n", a);
i=0;
a = (++i) * 2;
printf("i=0, (++i)*2=%d\n", a);
i=0;
a = (++i) * 2;
printf("i=0, (++i)*2=%d\n", a);
return 0;
}
Keluaran:
i=0, i++*2=0
i=0, ++i*2=2
i=0, (++i)*2=2
i=0, (++i)*2=2
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:
for(int i=0; i<10; i++)
memiliki efek yang sama
for(int i=0; i<10; ++i)
Untuk tidak membuat kebingungan antara kedua operator saya mengadopsi aturan ini:
Kaitkan posisi operator ++
sehubungan dengan variabel i
ke urutan ++
operasi sehubungan dengan penugasan
Diucapkan dengan kata lain:
++
sebelum i
berarti penambahan harus dilakukan sebelum penugasan;++
setelah i
sarana tambahan harus dilakukan setelah penugasan:Anda dapat menganggap konversi internal itu sebagai beberapa pernyataan ;
i++;
Anda bisa menganggapnya sebagai,
i;
i = i+1;
++i;
Anda bisa menganggapnya sebagai,
i = i+i;
i;
a = i ++ berarti a berisi nilai i saat ini a = ++ i berarti a berisi nilai i yang bertambah
a = i++;
berarti nilai yang disimpan dalam a
akan menjadi nilai i
sebelum kenaikan, tetapi 'tanpa penambahan' menyiratkan bahwa i
tidak bertambah, yang sama sekali salah - i
bertambah, tetapi nilai ekspresi adalah nilai sebelum kenaikan.
Berikut adalah contoh untuk memahami perbedaannya
int i=10;
printf("%d %d",i++,++i);
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, tetapi i
akan menjadi 11)
++i
-> i
peningkatan nilai dan mencetak nilai. (Mencetak 12, dan nilai i
juga 12)
i++
dan++i