Öncelikle, Henk ve Olivier'in cevapları doğrudur; Bunu biraz farklı bir şekilde açıklamak istiyorum. Özellikle, belirttiğiniz bu noktaya değinmek istiyorum. Şu ifadelere sahipsiniz:
int k = 10;
int c = 30;
k += c += k += c;
Ve sonra yanlış bir şekilde bunun şu ifadeler dizisiyle aynı sonucu vermesi gerektiği sonucuna varırsınız:
int k = 10;
int c = 30;
k += c;
c += k;
k += c;
Bunu nasıl yanlış anladığınızı ve bunu nasıl doğru yapacağınızı görmek bilgilendirici. Bunu parçalamanın doğru yolu şudur.
İlk olarak, en dıştaki + =
k = k + (c += k += c);
İkinci olarak, en dıştaki + 'yı yeniden yazın. Umarım x = y + z'nin her zaman "y'yi geçici olarak değerlendir, z'yi geçici olarak değerlendir, geçici değerleri toplamı, toplamı x'e atama" ile aynı olması gerektiğini kabul edersiniz . Öyleyse bunu çok açık hale getirelim:
int t1 = k;
int t2 = (c += k += c);
k = t1 + t2;
Bunun açık olduğundan emin olun, çünkü yanlış yaptığınız adım budur . Karmaşık işlemleri daha basit işlemlere böldüğünüzde, bunu yavaş ve dikkatli yaptığınızdan ve adımları atlamadığınızdan emin olmalısınız . Adımları atlamak, hata yaptığımız yerdir.
Tamam, şimdi tekrar, yavaş ve dikkatli bir şekilde t2'ye atamayı parçalayın.
int t1 = k;
int t2 = (c = c + (k += c));
k = t1 + t2;
Atama, c'ye atananla aynı değeri t2'ye atayacaktır, öyleyse şunu söyleyelim:
int t1 = k;
int t2 = c + (k += c);
c = t2;
k = t1 + t2;
Harika. Şimdi ikinci satırı parçalayın:
int t1 = k;
int t3 = c;
int t4 = (k += c);
int t2 = t3 + t4;
c = t2;
k = t1 + t2;
Harika, ilerleme kaydediyoruz. Atamayı t4'e ayırın:
int t1 = k;
int t3 = c;
int t4 = (k = k + c);
int t2 = t3 + t4;
c = t2;
k = t1 + t2;
Şimdi üçüncü satırı parçalayın:
int t1 = k;
int t3 = c;
int t4 = k + c;
k = t4;
int t2 = t3 + t4;
c = t2;
k = t1 + t2;
Ve şimdi her şeye bakabiliriz:
int k = 10;
int c = 30;
int t1 = k;
int t3 = c;
int t4 = k + c;
k = t4;
int t2 = t3 + t4;
c = t2;
k = t1 + t2;
Yani işimiz bittiğinde k 80 ve c 70'tir.
Şimdi bunun bilgi düzeyinde nasıl uygulandığına bakalım:
int t1 = k;
int t3 = c;
is implemented as
ldloc.0
ldloc.1
Şimdi bu biraz aldatıcı:
int t4 = k + c;
k = t4;
is implemented as
ldloc.0
ldloc.1
add
dup
stloc.0
Yukarıdakileri şu şekilde uygulayabilirdik:
ldloc.0
ldloc.1
add
stloc.0
ldloc.0
ama biz "dup" hilesini kullanırız çünkü kodu kısaltır ve seğirmeyi kolaylaştırır ve aynı sonucu alırız. Genel olarak, C # kod üreteci, yığın üzerinde mümkün olduğunca geçici "geçici" değerleri tutmaya çalışır. IL'yi daha az kısa ömürlü takip etmeyi daha kolay bulursanız, optimizasyonları kapatın ; kod oluşturucu daha az agresif olacaktır.
Şimdi c elde etmek için aynı numarayı yapmalıyız:
int t2 = t3 + t4;
c = t2;
is implemented as:
add
dup
stloc.1
ve sonunda:
k = t1 + t2;
is implemented as
add
stloc.0
Başka hiçbir şey için meblağa ihtiyacımız olmadığından, onu kopyalamıyoruz. Yığın artık boş ve açıklamanın sonundayız.
Hikayenin ahlakı şudur: Karmaşık bir programı anlamaya çalışırken, her zaman işlemleri birer birer parçalayın . Kestirme yollara gitmeyin; Seni saptırırlar.