Подтвердить что ты не робот

Один плюс плюс два компилятора неожиданно

Итак, я ожидаю, что это не будет компилироваться, и это не так:

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

Но это делает:

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

Что дает? Разве он не должен компилироваться?

Кроме того, этот вопрос очень сложно найти из-за операторов.

4b9b3361

Ответ 1

Java интерпретирует рабочий 1 + + 2 как 1 плюс положительный 2. См. раздел Unary operator.

Ответ 2

Из спецификации, Лексические переводы

Самый длинный возможный перевод используется на каждом шаге, даже если результат не в конечном итоге делает правильную программу, а другой лексический перевод. Есть одно исключение: если лексический перевод происходит в контексте типа (§ 4.11), и входной поток имеет два или более последовательных > символа, за которыми следует не- символ, то каждый символ должен быть переведен в токен для оператор численного сравнения > .

(Также известен как максимальный munch.)

++ интерпретируется как оператор приращения postfix, который нельзя применить к целочисленному литералу, поэтому ошибка компилятора.

Пока

1 + + 2

каждый символ интерпретируется отдельно. 1 - целочисленный литерал, + является аддитивным оператором , + является унарным плюсом оператора и 2 является целым литералом. Все выражение эквивалентно

1 + (+2)

который легче читать.

Ответ 3

В Java/С++/C ++ не то же самое, что и + +. ++/-- являются Приращение/Уменьшение оператора. Первый случай не работает, потому что он не применяется к литералам (1 или 2). Даже тогда это не было бы корректным утверждением, ни 1++ 2, ни 1 ++2 не являются допустимым выражением в Java. Второй пример работает, потому что он интерпретируется как 1 + (+2). Java lexer игнорирует пробел. Точно так же это верно:

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

или

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

Он работает только потому, что + является оператором unary. Он не работает для строк, как показано ниже:

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

Аналогично это недействительно с умножением

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

Ответ 4

Сообщение:

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

Оператор 1 ++ 2 анализируется как 1, за которым следует ++, а затем 2. Это интерпретируется как 1++ и 2, создавая синтаксическую ошибку (а не ошибку unexpected type, на самом деле, вы получите ту же ошибку, если используете переменные, например i ++ j).


С другой стороны, оператор 1 + + 2 анализируется как 1, за которым следует +, за которым следует +2, который компилируется, как ожидалось. Пространство между двумя операторами разделяет два оператора.

Ответ 5

Иногда легче видеть проблему с использованием переменных.

Ваш фрагмент можно переписать как:

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

Теперь вы можете легко увидеть, что второй оператор + используется для указания положительного значения. Вы также могли бы написать +1 + +2.

Оператор - может использоваться для отрицания выражения.

+ и - являются унарными операторами.