C, kullanma arasındaki fark ne ++i
ve i++
ve hangi bir artırılmaz blok kullanılmalıdır for
döngü?
C, kullanma arasındaki fark ne ++i
ve i++
ve hangi bir artırılmaz blok kullanılmalıdır for
döngü?
Yanıtlar:
++i
değerini artırır i
ve sonra da artan değeri döndürür.
i = 1;
j = ++i;
(i is 2, j is 2)
i++
değerini artırır i
, ancak i
artırılmadan önce tutulan orijinal değeri döndürür .
i = 1;
j = i++;
(i is 2, j is 1)
Bir for
döngü için her ikisi de çalışır. ++i
belki de K & R'de kullanılan şey budur .
Her durumda, "tercih kılavuz takip ++i
üzerinde i++
" ve yanlış gitmeyecek.
Verimliliğini ilgili yorumların bir çift var ++i
ve i++
. Öğrenci olmayan proje derleyicilerinde performans farkı olmayacaktır. Aynı olacak oluşturulan koda bakarak bunu doğrulayabilirsiniz.
Verimlilik sorusu ilginç ... İşte benim yanıtımdaki girişim: C'de i ++ ve ++ i arasında bir performans farkı var mı?
Şöyle @OnFreund yana notları, bu C ++ nesne için farklı operator++()
bir fonksiyonudur ve derleyici ara değer tutmak için geçici bir nesne oluşturma uzak optimize bilemez.
for(int i=0; i<10; i++){ print i; }
bu for(int i=0; i<10; ++i){ print i; }
benim anlayışımdan farklı olmayacak mı, bazı diller kullandığınız şekle bağlı olarak size farklı sonuçlar verecektir.
i++
dolayı, "işlenen-işleç" biçiminde, "işlenen-işleç-değer" ataması şeklinde tercih ederim . Başka bir deyişle, hedef işlenen, tıpkı bir atama ifadesinde olduğu gibi ifadenin sol tarafındadır.
i++
ve print i
farklı tablolara, ancak çünkü i++;
ve i<10
vardır. @ jonnyflash'ın sözleri bu tabandan değil. Varsayalım for(int i=0; i++<10){ print i; }
ve for(int i=0; ++i<10){ print i; }
. Bunlar, @johnnyflash'ın ilk yorumda açıklanan şekilde farklı şekilde çalışacaktır.
i ++ , Artış Sonrası olarak bilinirken, ++ i'ye Ön Artış denir .
i++
i++
i
işlem bittikten sonra değerini 1 artırır, çünkü işlem bittikten sonra değerini 1 artırır .
Aşağıdaki örneğe bakalım:
int i = 1, j;
j = i++;
Burada j = 1
ama değeri i = 2
. Burada değeri i
önce atanacak j
sonra i
artırılacaktır.
++i
++i
i
operasyondan önce değerini 1 arttırdığı için ön artıştır . j = i;
Sonra yürütülecek demektir i++
.
Aşağıdaki örneğe bakalım:
int i = 1, j;
j = ++i;
Burada j = 2
ama değeri i = 2
. Burada değeri, değerinin artırılmasından sonra i
atanacaktır . Benzer şekilde daha önce icra edilecektir .j
i
i
++i
j=i;
Sorunuz için bir for döngüsünün artış bloğunda hangisi kullanılmalıdır? cevap, herhangi birini kullanabilirsiniz .. önemli değil. Aynı döngü için for yürütecek. kez.
for(i=0; i<5; i++)
printf("%d ",i);
Ve
for(i=0; i<5; ++i)
printf("%d ",i);
Her iki döngü de aynı çıktıyı üretecektir. yani 0 1 2 3 4
.
Sadece nerede kullandığınız önemlidir.
for(i = 0; i<5;)
printf("%d ",++i);
Bu durumda çıktı olacaktır 1 2 3 4 5
.
Lütfen daha hızlı olan "verimlilik" (hız, gerçekten) konusunda endişelenmeyin. Bugünlerde bu şeylerle ilgilenen derleyicilerimiz var. Niyetinizi daha açık bir şekilde gösteren, hangisinin kullanılması mantıklı olursa kullanın.
operator++(int)
(postfix sürümü) içinde kodun hemen hemen döndürülecek bir geçici oluşturması gerekir. Derleyicilerin bunu her zaman optimize edebileceğinden emin misiniz?
++i
değeri artırır, sonra döndürür.
i++
değeri döndürür ve sonra artırır.
İnce bir fark.
For döngüsü için, ++i
biraz daha hızlı olduğu için kullanın . i++
sadece atılan ekstra bir kopya oluşturur.
i++
: Bu senaryoda önce değer atanır ve sonra artış olur.
++i
: Bu senaryoda önce artış yapılır ve sonra değer atanır
Aşağıda görüntü görselleştirme ve burada da aynı şeyi gösteren güzel bir pratik video var.
Nedeni ++i
olabilir biraz daha hızlı olması i++
DİR i++
o artırılır hale geçmeden iken, i değerinin yerel bir kopyasını gerektirebilir ++i
yapmaz. Bazı durumlarda, bazı derleyiciler mümkünse onu optimize eder ... ancak her zaman mümkün değildir ve tüm derleyiciler bunu yapmaz.
Derleyici optimizasyonlarına çok fazla güvenmemeye çalışıyorum, bu yüzden Ryan Fox'un tavsiyelerine uyuyorum: her ikisini de kullanabildiğimde kullanıyorum ++i
.
i
Bir ifade yazdığınızda değerin "yerel kopyası" diye bir değer kalmaz 1;
.
Bir döngüde kullanılmasının etkili sonucu aynıdır. Başka bir deyişle, döngü her iki durumda da aynı şeyi yapar.
Verimlilik açısından, ++ i üzerinden i ++ seçimi ile ilgili bir ceza olabilir. Dil spesifikasyonu açısından, artım sonrası operatörünün kullanılması, operatörün hareket ettiği değerin fazladan bir kopyasını oluşturmalıdır. Bu, fazladan bir işlem kaynağı olabilir.
Ancak, önceki mantıkla ilgili iki ana sorunu göz önünde bulundurmalısınız.
Modern derleyiciler harika. Tüm iyi derleyiciler, for-loop'ta bir tamsayı artışı gördüğünü anlayacak kadar akıllıdır ve her iki yöntemi de aynı verimli koda optimize edecektir. Artım öncesi artış sonrası kullanmak aslında programınızın daha yavaş çalışma süresine neden oluyorsa, korkunç bir derleyici kullanıyorsunuz demektir .
Operasyonel zaman karmaşıklığı açısından, iki yöntem (bir kopya gerçekte yapılsa bile) eşdeğerdir. Döngü içinde gerçekleştirilen talimat sayısı, arttırma işlemindeki işlem sayısına önemli ölçüde hakim olmalıdır. Bu nedenle, önemli boyuttaki herhangi bir döngüde, artış yönteminin cezası, döngü gövdesinin yürütülmesi ile büyük ölçüde gölgede bırakılacaktır. Başka bir deyişle, kodu artımdan ziyade döngüdeki optimize etme konusunda endişelenmeniz çok daha iyidir.
Benim düşünceme göre, tüm sorun sadece bir stil tercihine bağlı. Ön artışın daha okunabilir olduğunu düşünüyorsanız, onu kullanın. Şahsen, artımı sonrası tercih ederim, ancak bunun nedeni muhtemelen optimizasyon hakkında bir şey bilmeden önce bana öğretilen şeydi.
Bu, erken optimizasyonun özet bir örneğidir ve bunun gibi sorunlar, bizi tasarımdaki ciddi sorunlardan uzaklaştırma potansiyeline sahiptir. Bununla birlikte, hala sorulması iyi bir soru, çünkü "en iyi uygulamada" kullanımda tekdüze veya fikir birliği yoktur.
Her ikisi de sayıyı arttırır. ++i
eşittir i = i + 1
.
i++
ve ++i
çok benzer ancak tam olarak aynı değil. Her ikisi de sayıyı artırır, ancak ++i
geçerli ifade değerlendirilmeden önce sayıyı i++
artırır, ifade ifade edildikten sonraki sayıyı artırır.
Misal:
int i = 1;
int x = i++; //x is 1, i is 2
int y = ++i; //y is 3, i is 3
++i
(Önek çalışma): o artımlarla ve değer atar
(örneğin) int i = 5
, int b = ++i
bu durumda, 6, 7 ve böylece ilk ve sonra artışlarla b atanır.
i++
(Postfix'i çalışma): o atar ve değerini artırır
(örneğin) int i = 5
, int b = i++
bu durumda, 5, 6 ve bu şekilde birinci ve daha sonra artışlarla b atanır.
For loop i++
örneği : çoğunlukla kullanılır, çünkü normalde for döngüsünü artırmadan i
önce başlangıç değerini kullanırız . Ancak program mantığınıza bağlı olarak değişebilir.
Semantikteki farkı şimdi anladığınızı varsayıyorum (dürüst olmak gerekirse, insanların neden okumak, bilirsiniz, bir kitap veya web öğreticisi veya başka bir şey yerine yığın taşması hakkında neden 'operatör X'in ne anlama geldiğini' 'sorduğunu merak ediyorum.
Ama yine de, hangisini kullanacağı kadarıyla, C ++ 'da bile olası olmayan performans sorularını göz ardı edin. Hangisini kullanacağınıza karar verirken kullanmanız gereken prensip budur:
Kodda ne demek istediğinizi söyleyin.
İfadenizde artımdan önceki değere ihtiyacınız yoksa, operatörün bu formunu kullanmayın. Bu küçük bir sorundur, ancak bir sürümü diğeri lehine yasaklayan bir stil kılavuzu ile çalışmadığınız sürece (kemik başlı stil kılavuzu olarak da bilinir), yapmaya çalıştığınız şeyi tam olarak ifade eden formu kullanmalısınız.
QED, artış öncesi sürümünü kullanın:
for (int i = 0; i != X; ++i) ...
Fark aşağıdaki basit C ++ kodu ile anlaşılabilir:
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;
Temel Fark:
- i ++ Post ( Artıştan Sonra ) ve
++ i Pre ( Arttırmadan Önce )
i =1
döngü aşağıdaki gibi artarsa1,2,3,4,n
- öncesi
i =1
döngü aşağıdaki gibi artarsa2,3,4,5,n
Bu küçük kod, farkı önceden gönderilen cevaplardan farklı bir açıdan görselleştirmeye yardımcı olabilir:
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);
Sonuç:
//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
Önceki ve sonraki durumlara dikkat edin.
Bunlardan hangisinin bir for döngüsünün artım bloğunda kullanılması gerektiğine göre, bir karar vermek için yapabileceğimiz en iyi şeyin iyi bir örnek kullanmak olduğunu düşünüyorum:
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);
Sonuç:
> iteration #0 > iteration #1 > iteration #2 > iteration #3
> iteration #0 > iteration #1 > iteration #2 > iteration #3
Seni bilmiyorum, ama en azından bir for döngüsünde kullanımında herhangi bir fark görmüyorum.
Aşağıdaki C kodu parçası, öncesi ve sonrası artış ve azalma operatörleri arasındaki farkı gösterir:
int i;
int j;
Artış operatörleri:
i = 1;
j = ++i; // i is now 2, j is also 2
j = i++; // i is now 3, j is 2
Ön-krem aynı çizgide artış anlamına gelir. Artış sonrası, satır yürütüldükten sonra artış anlamına gelir.
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
OR VE VE operatörleri ile birlikte geldiğinde daha ilginç hale gelir.
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
}
Dizide
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
}
C ++ post / pointer değişkeninin ön artışı
#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)
}
kısaca:
++i
ve i++
bir işlevde yazmıyorsanız aynı şekilde çalışır. Gibi bir şey kullanırsanız function(i++)
veya function(++i)
farkı görebilirsiniz.
function(++i)
ilk i i 1 'i arttırır, bundan sonra bunu i
yeni değer ile fonksiyona sokar.
function(i++)
1 ile i
bu artıştan sonra ilk önce fonksiyona girdiğini söylüyor i
.
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;
ve int k = i++;
hatta aralarında bir fark vardır.
Tek fark, değişkenin artışı ile operatörün döndürdüğü değer arasındaki işlemlerin sırasıdır.
Bu kod ve çıktısı farkı açıklar:
#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);
}
Çıktı:
i before: 1; value returned by i++: 0, i after: 1
i before: 1; value returned by ++i: 1, i after: 1
Temelde ++i
değeri artırıldıktan sonra döndürür, değeri artırılmadan ++i
önce döndürür. Sonunda, her iki durumda da i
iradenin değeri artırılır.
Başka bir örnek:
#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;
}
Çıktı:
i=0, i++*2=0
i=0, ++i*2=2
i=0, (++i)*2=2
i=0, (++i)*2=2
Döndürülen değeri bir değişken ya da arttırma işlemleri öncelik uygulandığı başka işlemler ile birleştirme gerçekleştirilir (zaman atandığında farklar açık i++*2
farklıdır ++i*2
, ancak (i++)*2
ve (++i)*2
bir çok durumda, aynı değere döner) kendi aralarında değiştirilebilir. Klasik bir örnek for döngüsü sözdizimidir:
for(int i=0; i<10; i++)
aynı etkiye sahiptir
for(int i=0; i<10; ++i)
İki operatör arasında kafa karışıklığı yaratmamak için bu kuralı kabul ettim:
Operatörün ++
değişkene göre pozisyonunu , göreve göre operasyonun i
sırasına ++
göre ilişkilendirin
Başka bir deyişle:
++
önce i
, atamadan önce artım yapılmalıdır ;++
sonra i
araçların artırılması atamadan sonra yapılmalıdır :Bunun içsel dönüşümünü birden çok ifade olarak düşünebilirsiniz ;
i++;
olarak düşünebilirsiniz,
i;
i = i+1;
++i;
olarak düşünebilirsiniz,
i = i+i;
i;
a = i ++, mevcut i değerini içeren anlamına gelir a = ++ i, artırılmış i değerini içeren anlamına gelir
a = i++;
burada depolanan a
değerin i
, artıştan önceki değer olacağı , ancak 'arttırmadan', i
artırılmamış, yani tamamen yanlış olanın artırıldığı anlamına gelir i
, ancak ifadenin değeri, artıştan önceki değerdir.
İşte farkı anlamak için örnek
int i=10;
printf("%d %d",i++,++i);
çıktı: 10 12/11 11
( printf
derleyiciler ve mimariler arasında değişen işleve yönelik argümanların değerlendirme sırasına bağlı olarak )
Açıklama:
i++
-> i
yazdırılır ve sonra artar. (10 yazdırır, ancak i
11 olur)
++i
-> i
değer artar ve değeri yazdırır. (Baskı 12 ve ayrıca değeri i
12)
i++
Ve++i