Member 11735960 Ответов: 1

Каков выход для этой JAVA-программы?


код начинается:
&низкотемпературный;
классная Лаборатория{
public static void main(String args[]){
int i=10;
я*=я + + + я;
Системы.из.код println(я);
}
}
>
код заканчивается

Я знаю, что здесь используется приоритет оператора. В этом случае правая сторона равна 21, исключая умножение "i". Теперь я не могу понять, как 210-это ответ. После получения 21 на RHS, не должен ли он умножиться на обновленное значение 'i' 11?

Что я уже пробовал:

Я попробовал вышеприведенную программу, и результат был: 210

1 Ответов

Рейтинг:
2

OriginalGriff

Нет.
i++ говорит: "получите значение i, а затем добавьте к нему единицу", и обработка работает слева направо

i *= i++ + i
i = i * (i++ + i)
i = 10 * (i++ + i)
i = 10 * (10 + i)
i = 10 * (10 + 11)
i = 10 * 21
i = 210

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


"почему логика, которую я объяснил выше, неверна?"


Дело не в приоритете, а в порядке исполнения.
A * B + C * D

Приоритет очевиден: A * B и C * D должны быть полностью оценены, прежде чем вы сможете сложить их вместе. Но... сложение коммутативно: так что не имеет значения, если вы поменяете их местами:
C * D + A * B

Даст вам тот же результат.
Как будет
B * A + D * C
Потому что умножение также коммутативно.
И спецификация языка не говорит, что выражения должны быть вычислены в каком-либо определенном порядке (за исключением случая булевых операторов, где они указаны строго слева направо).
В результате компилятор (и автор компилятора) волен сам решать, какой порядок лучше для него или конкретного процессора. Возможно даже, что разные части целого выражения могут быть распределены по разным ядрам в одном и том же процессоре одновременно, при условии, что бит слева и бит справа от "+" будут полностью вычислены до завершения сложения.

А теперь ..... самое сложное. О да, все становится сложнее.
Что делает x++? Или, точнее, когда это делается? Опять же, очень немногие языки на самом деле точно определяют, что происходит. Решение о том, как его оценивать, остается за автором компилятора. Способ, которым вы его разрабатываете, заключается в том, чтобы" расширить " выражение
i *= i++ + i;
как
temp = i;
i = i + 1;
temp = temp + i;
i = temp * i;
Но компилятор это не так:
result = i;
temp = i;
i = i + 1;
temp = temp + i;
result = result * temp;

И это только один способ расширить его-есть, по крайней мере, два других, которые я могу придумать с самого начала, которые дадут еще более разные результаты!

Как я уже сказал: Не делай ничего подобного. Вы оставляете себя открытым для множества будущих проблем!


Member 11735960

Поскольку значение " i " самое позднее равно 11, разве оно не должно быть 21x11?

OriginalGriff

Нет, потому что он не увеличивается до тех пор, пока не будет извлечен и использован i++.
Понимаете, что я имею в виду, говоря о трудном для чтения и понимания?
На самом деле это становится хуже в некоторых языках: попробуйте то же самое в C++, и вы можете получить четыре разных результата от четырех разных компиляторов, потому что порядок выполнения не определен спецификацией языка (в отличие от приоритета оператора, который не имеет реального влияния в этом примере).

Member 11735960

Я все еще в замешательстве. Позвольте мне попытаться объяснить еще раз. Согласно приоритету оператора, постфиксный оператор имеет больший приоритет, чем оператор умножения. Операнды внутри круглых скобок имеют больший приоритет.

Оценивая их сначала: i*(i++ + i)
Итак, теперь в скобках 10+11: i*(21)

Текущее значение i равно 11

Во-вторых, оценивая оператор умножения из-за следующего приоритета, не должен ли он быть 11*21=231?

Хотя я знаю, что ответ 210, почему логика, которую я объяснил выше, неверна?

OriginalGriff

Ответ обновлен.