2013-05-10 27 views
7

i ~ üstünlüğü ve ++ java

111 
11111111111111111111111111111001 

ilk ben bunun olabileceğini düşündüm görmeyi bekleyen ben ne bu kod parçacığı

int j = 7; 
System.out.println(Integer.toBinaryString(j)); 
j = ~j++; 
System.out.println(Integer.toBinaryString(j)); 

baskılar

111 
11111111111111111111111111111000 

düşünün t ve eğer + ve ++

'un önceliği t ++ Ben Oracle tutorials arandı ~

11111111111111111111111111110111 

önce değerlendirilir eğer o ~ cevabı başka

11111111111111111111111111111001 

olacak ++ önce değerlendirilir ama cevabını bulamadık. Bu davranışı herkes açıklayabilir mi?

+3

Kimse bu şekilde kod yazmamalıdır. – duffymo

+0

j = ~ (++ j) 'yi denediniz mi ve karşılaştırdınız mı? – BlackVegetable

+2

Hm ... Java'da bu tanımlı davranış nedir? Ödevin her iki tarafında j'yi değiştiriyorsunuz. J = j ++ 'yi denediyseniz bile beklenmedik sonuçlar alabilirsiniz. Yani bu gerçekten bir öncelik meselesi değil. – Axel

cevap

6

'++' Artış sonrası işlecinin, artışından önce j değerini döndürdüğünü unutmayın. Yani, 'j' 7 ise, o zaman 'j ++' j'yi 8, olarak ayarlar, ancak 7 döndürür. ~ 7, daha sonra gördüğünüz çıktı, üç 0 bit ile biten sayıdır.

'+' Artış sonrası arttırma operatörü sadece "L-değerleri" olarak adlandırılabilir. Bir L değeri, kodun mantıksal olarak referans gösterebileceği bir yerde gerçekte var olan bir değerdir - bir değişken veya bir dizi öğesi, bir parametre veya sınıf alanı. Bir L-değerinin değerini alır almaz ve ona sayısal bir işlem uygularsanız, bir R-değeri alırsınız. R değerleri değeridir ve yalnızca değeridir ve sonuç alınabilecek kalıcı depolamaya başvurmazlar. L değerlerine atayabilir, ancak R-değerlerine atamazsınız - ve eğer bir R-değeri '++' denediyseniz, bir derleme hatası alırsınız.

Eğer '~' operatörü ilk önce gelirse, (~ j) ++ 'da olduğu gibi bir R-değeri olacak şekilde ++ olacaktır. Bu derleme olmazdı. Kodun derlemesi aslında önceliğin başka bir yol olduğu anlamına gelir: ~ (j ++).

  1. hakkında emin değilseniz özgün yol: Sadece üç test durumları yazma: Böyle

    Parantez herhangi bir karışıklık olduğunda size öncelik halledene bildiğim en basit yoldur.

  2. Bir işlem sırasını zorlayan parantezler.
  3. Diğer işlem sırasını zorlayan parantezler.

çalıştırın o olup olmadığı # 2 ya da 3 e bakınız # 1 ile aynı sonucu verir.

+0

, belirtilen j = (~ j) ++ derleme hatası verir ~ (j ++), ++ ++ daha yüksek önceliğe sahip olduğundan ~ j ++ 'ya eşdeğerdir –

+1

+1 Çok güzel yanıt, özellikle r değeri/l değeri. – Dukeling

0

İlk önce bunu yapma. Bunun gibi operatörleri tek bir ifade haline getirmenin bir sebebi yok, ama bunun gerçekten canlı bir koda yer vermeyi planladığınızı ve sadece denemediğini anlıyorum. Java operatörü önceliği için şu sayfayı deneyin: http://bmanolov.free.fr/javaoperators.php

+0

linkte belirtildiği gibi, postfix artışı ~ 'dan önce değerlendirilir, sonra cevap inkrement first: 00 ..... 01000 olmalıdır. daha sonra tamamlar: 11 ..... 10111 –

+0

Bu, linkten istenen bilgileri gerçekten çıkarmaz ve bir açıklama ile cevabın içine koymazsanız, bir yorum olmalıydı. – Dukeling

+0

lütfen açıkladığım bir şey varsa lütfen açıkladım ben ++ (pre- veya postfix increment) daha yüksek önceliği vardır ve her ikisi de doğru birliği var –

1

Kod çok kırılgan görünüyor. Sanırım, "~ i ++" ifadesi değerlendirildiğinde "~ i" değerinin çıkarıldığı, "i ++" işleminin gerçekleştirildiği ve son olarak atama (önceki değeri "i ++" den geçersiz kılan) olduğudır.

+2

~ 8 111111111111111111111111111111111111110111 değil, 11111111111111111111111111111000 Düzenleme: Düzenlemenizi gördüm :-) Ancak, yine de geri siparişiniz var. ++ önce olur, ama ++ sonucu 7 değil 8. –

+0

-8 ile kolayca karıştı. Bir an kafam karıştı ve bu cevabın doğru olduğunu düşündüm. – BlackVegetable

+0

Evet, başlangıçta kafam karıştı. Cevap vermeden önce biraz daha düşünmeli. – ctn

1

Her iki operatör de doğru birleştirici ikinci derece operatörlerdir, ancak basit bir test, ilk olarak çalıştırılan ++ ve BITWISE NOT'un ikinciyi çalıştırdığını gösterir.

int j = 7, z = 7, k = 7; 
z = z++; 
z = ~z; 
k = ~k++; 
j = ~j; 
j++; 
System.out.println(Integer.toBinaryString(z)); 
// 11111111111111111111111111111000 
System.out.println(Integer.toBinaryString(j)); 
// 11111111111111111111111111111001 
System.out.println(Integer.toBinaryString(k)); 
// 11111111111111111111111111111000 
1

Tekli operatörler (++1, --, +, -, ~, !) sağdan sola doğru değerlendirilir. Dolayısıyla ++, ~'dan önce değerlendirilmiştir.