Приоритет ++ и - операторов в Java - PullRequest
9 голосов
/ 16 июня 2011

Я прочитал из официального руководства по Java, что префикс и постфикс ++ имеют разные приоритеты:

Постфикс: expr ++ expr -

унарный: ++ expr --expr + expr -expr ~!

Операторы

Согласно учебнику, не должно ли это

d = 1; System.out.println(d++ + ++d);

распечатать 6 (d++ делает d 2, ++d делает 3) вместо 4?

Я знаю объяснение того, как ++d вычисляется заранее, но если d++ имеетболее высокий приоритет, чем ++d, почему d++ не оценивается первым?И более того, в каком случае d++ показывает, что он имеет более высокий приоритет?

РЕДАКТИРОВАТЬ:

Я пробовал следующее:

d = 1; System.out.println(++d * d++);

Возвращает 4. Кажется, что это должно быть 2 * 2 вместо 1 * 3.

Ответы [ 10 ]

13 голосов
/ 16 июня 2011

Внутри оператора println эта операция (d ++) + (++ d)

  1. Таким образом, значение d читается (d = 1)
  2. текущее значение d (1) помещается в функцию сложения
  3. значение d увеличивается (d = 2).

  4. Затем, нас правой стороны значение d читается как (2)

  5. Значение d увеличивается (теперь d = 3)
  6. Наконец, значение d (3) добавляется в функцию сложения

    , поэтому 1 + 3 приводит к редактированию 4

: извините за формат, я довольно плохо пользуюсь спискомха-ха

10 голосов
/ 16 июня 2011

Ключ - это то, что возвращается из операции.

  • x ++ изменяет значение x, но возвращает старое x.
  • ++ x изменяет значение x,и возвращает новое значение.
d=1
System.out.println(d++ + ++d); // d is 1
System.out.println(1 + ++d); // d is 2
System.out.println(1 + 3); // d is 3

Печать 4

7 голосов
/ 16 июня 2011

Другой приоритет не означает, что будет оцениваться первым .

Это означает выражения будут сгруппированы таким образом .

В этом случае d++ + ++d будет сгруппировано (d++) + (++d), и это двоичное выражение будет оцениваться в следующем порядке:

  • левый операнд d++. Это подвыражение состоит из оператора приращения постфикса и переменной, поэтому имеет два следующих эффекта:
    • Значение подвыражения: 1
    • переменная обновлена: d = 2
  • правый операнд ++d. Это подвыражение состоит из префиксного оператора приращения и переменной, поэтому имеет два следующих эффекта:
    • Переменная обновлена: d = 3
    • Значение подвыражения: 3
  • оператор + вычисляется с использованием значений двух операндов.
    • Таким образом, значение выражения равно 1 + 3 = 4.

Различный приоритет между префиксной и постфиксной формами ++ будет виден только в ++d++, что будет интерпретироваться как ++(d++) - и это не имеет никакого значения (у (++d)++ тоже нет никого), поскольку ++ работает только с переменными, а не со значениями (а результатом является значение).

2 голосов
/ 16 июня 2011

См. Почему этот приоритет Java-оператора здесь игнорируется? .

Это сводится к тому, что оператор postfix вычисляется первым, но возвращает исходное значениепеременной , как задумано.Итак, для целей вашей операции:

(d++ + ++d)

Processes as:
1. d++ evaluates, returning the original value of 1 but incrementing d to 2
2. ++d evaluates, incrementing the value of 2 TO 3, and returning 3
3. +   evaluates, resulting in 1 + 3

Путаница не в порядке приоритета для оценки токенов, вы имеете это право.Настоящая проблема заключается в понимании функциональной разницы между постфиксными и префиксными операторами.

2 голосов
/ 16 июня 2011

Речь идет не о приоритете, а о порядке оценки. d++ оценивается как 1, но затем d увеличивается. ++d увеличивает d, а затем оценивает до 3.

0 голосов
/ 22 апреля 2018

Это распространенная ошибка. Даже в руководстве по сертификации оракула говорится, что операторы Post приращения и уменьшения имеют более высокий приоритет, чем операторы Pre.

Я полагаю, что это ошибка, которую многие люди совершали некоторое время. После экспериментов с несколькими выражениями. Я уверен, что могу с уверенностью сказать, что пре- и пост-операторы имеют одинаковые приоритеты и оцениваются слева направо.

Вы можете поэкспериментировать, оценив следующие примеры, чтобы подтвердить для себя.

int y = 4;
int x = --y * 2 + 3 + y-- * 2;      // x is 15

int y = 4;
int x = --y * 2 + 3 + y++ * 2;      // x is 15
0 голосов
/ 29 сентября 2013

Я прошел через все объяснения сверху. В соответствии с пониманием, следующий код должен дать 11.0, тогда y даст 10.0. двойной х = 4,5; х = х + ++ х; // х получает значение 10,0.

0 голосов
/ 16 июня 2011

В дополнение к другим комментариям, я предлагаю вам взглянуть на точки последовательности, так как некоторые из этих вещей могут привести к неопределенному поведению, хотя я думаю, что ваш случай определен для java.

Что означает x[i]=i++ + 1; до?

http://www.angelikalanger.com/Articles/VSJ/SequencePoints/SequencePoints.html

0 голосов
/ 16 июня 2011

System.out.println (d ++ + ++ d);

Вот как это происходит:

++ d выполняется, поэтому d теперь равно 2.

d + d выполняется, что равно 4.

Значение 4 присваивается System.out.println ()

d ++ выполняется, поэтому теперь d равно 3.

0 голосов
/ 16 июня 2011

d имеет значение 1

d ++ оценивается;его значение равно 1, а d равно 2 (post ++ возвращает значение до приращения)

++ d оценивается;это значение равно 3, а d теперь равно 3 (++ предварительно возвращает значение после приращения)

1 + 3 = 4

...