2014-12-23 16 views
30

Tak, spodziewam się to nie skompilować, a nie:jeden plus plus dwa kompiluje niespodziewanie

// the two is inc'd, so reduces symbolically to println(int int) 
// which is a compile error 
System.out.println(1 ++ 2); 

Ale to robi:

System.out.println(1 + + 2); // returns three 

Co daje? Czy nie powinien także się kompilować?

Również ta kwestia jest bardzo ciężko, aby szukać powodu operatorów ..

+1

++ jest operatorem przyrost więc kompilator może spodziewać się nazwę zmiennej przed albo po ++ – ryekayo

+12

W drugim przypadku '' + jest operatorem „cukier syntaktyczny” (mirroring '-'), który nie robi nic do operand. –

+4

* "To pytanie jest bardzo trudne do wyszukania ze względu na operatorów .." * Dlaczego nie szukać "operatorów Java"? Otrzymasz listę operatorów i wymienionych operatorów. – Radiodef

Odpowiedz

65

Java interpretacji roboczą 1 + + 2 jako 1 plus dodatni 2. Patrz Unary operator section.

+7

Chociaż nie tak szczegółowe, jak inne poprawne odpowiedzi, ten był dość szybki do przeanalizowania i zrozumienia. – jabgibson

+8

Czasami szczegółowy podział specyfikacji nie jest potrzebny. Czasami najlepszą odpowiedzią jest najprostsza. :) –

41

ze specyfikacji, na Lexical Translations

Najdłuższy możliwy tłumaczeń jest stosowany na każdym kroku, nawet jeśli wynik nie ostatecznie złożyć odpowiedni program, podczas gdy inny tłumaczenie leksykalny będzie. Jest jeden wyjątek: jeśli tłumaczenie leksykalne występuje w kontekście typu (§4.11), a strumień wejściowy ma co najmniej dwa kolejne> znaki, po których występuje znak inny niż , to każdy znak musi zostać przetłumaczony na token dla operatora porównania liczb> .

(znany również jako maximal munch).

++ jest interpretowane jako postfix increment operator, które nie mogą być stosowane do całkowitej dosłownym, tak więc problem kompilatora.

Podczas

1 + + 2 

każdy znak jest interpretować oddzielnie. 1 jest liczbą całkowitą dosłowną, + jest additive operator, + jest unary plus operator, a 2 jest liczbą całkowitą dosłowną. Całe wyrażenie jest równoważne z wartością, która jest łatwiejsza do odczytania. Jest to odpowiednik dla:

1 + (+2) 

.

6

W języku Java/C++/C ++ nie jest tożsamy ​​z + +. ++/-- to Increment/Decrement operator. Pierwszy przypadek nie działa, ponieważ nie ma zastosowania do literałów (1 lub 2). Nawet wtedy nie byłoby to prawidłowe oświadczenie, Ani 1++ 2, ani nie są poprawnymi instrukcjami w Javie. Drugi przykład działa, ponieważ jest interpretowany jako 1 + (+2). Lexer Java ignoruje białe znaki. W ten sam sposób, to jest ważne:

1 + + + 2 --> 1 + (+ (+2)) 

Albo

1 + + + + + + + + + + + + + + + + + + + + + + + + + + + 2 

Działa tylko dlatego + jest operatorem unary.To nie działa na smyczki, jak poniżej:

"a" + + "b" // does not work because +"b" is not valid. 

Podobnie nie jest ważne z mnożenia

1 * * 2  // does not work because *2 is not valid. 
+1

To nie jest w porządku powiedzieć, że lexer ignoruje białe spacje, co? W końcu nie interpretuje '1 ++ 2' jako' int biplus unplus int', ani '1+ + 2' jako' int incr int' – djeikyb

3

Przesłanie brzmi:

Main.java:14: error: ')' expected 
     System.out.println(1 ++ 2); 
          ^

Oświadczenie 1 ++ 2 jest analizowany jako 1 następnie ++, po której następuje 2. Jest to interpretowane jako 1++ i 2 tworzenie błędu składni (a nie błędu unexpected type, w rzeczywistości otrzymasz ten sam błąd, jeśli użyłeś zmiennych, np. i ++ j).


Oświadczenie 1 + + 2 z drugiej strony jest analizowany jako 1 następnie + następnie +2 który kompiluje jak oczekiwano. Przestrzeń pomiędzy dwoma operatorami oddziela dwa operatory.

3

Czasami łatwiej jest zauważyć problem z użyciem zmiennych.

Twój fragment może być zapisane jako:

int a = 1; 
int b = +2; 
System.out.println(a + b); 

Teraz można łatwo zobaczyć, że drugi operator + służy do wskazania wartość dodatnią. Można również napisać +1 + +2.

Operator - może zostać użyty do zanegowania wyrażenia.

+ i - są operatorami jednokierunkowymi.