Комментарии 66
+1
Так 8 же. Ничего удивительного.
+5
а как же скобки, они ведь должны первыми выполнятся, ну т.е. выражение в скобках?
-1
Унарные операции имеют приоритет выше, чем умножение и сложение.
Разбор:
b = a++ + (--a * ++a)
Сначала выражение в скобках
*в нём
**сначала унарные операции, затем умножение:
***a = a-- => a = 1
***a = a++ => a = 2
**делаем операцию в скобках (умножение), получаем (2 * 2) = 4
Далее сложение, но сначала унарная операция инкримента
*a = a++ => a = 4
Результат:
4 + 4 = 8
Разбор:
b = a++ + (--a * ++a)
Сначала выражение в скобках
*в нём
**сначала унарные операции, затем умножение:
***a = a-- => a = 1
***a = a++ => a = 2
**делаем операцию в скобках (умножение), получаем (2 * 2) = 4
Далее сложение, но сначала унарная операция инкримента
*a = a++ => a = 4
Результат:
4 + 4 = 8
-4
ну нет, тогда должно быть так:
1) выполняется выражение в скобках: --a * ++a
--a уменьшает а на 1 (было 2, стало 1) и возвращает ее значение
++а увеличивает а на 1 (было 1, стало 2) и возвращает ее значение
получается результат (1 * 2)=2
2) а++ + 2
а++ возвращает значение а (сейчас равное 2) и инкрементирует а после операции
2 + 2 = 4
т.е. b=4, а=3 вроде как должно быть ((=
1) выполняется выражение в скобках: --a * ++a
--a уменьшает а на 1 (было 2, стало 1) и возвращает ее значение
++а увеличивает а на 1 (было 1, стало 2) и возвращает ее значение
получается результат (1 * 2)=2
2) а++ + 2
а++ возвращает значение а (сейчас равное 2) и инкрементирует а после операции
2 + 2 = 4
т.е. b=4, а=3 вроде как должно быть ((=
0
Как у вас в результате a++ 4 получилось?
+2
А если записать так
b=(a++) + (--a * ++a)
Всё становится на свои места? А скобки то незначащие :)
b=(a++) + (--a * ++a)
Всё становится на свои места? А скобки то незначащие :)
0
НЛО прилетело и опубликовало эту надпись здесь
Консоль фаербага выдаёт 8. Как я понимаю
a++ возвращает 2 и увеличивает переменную «a» до 3.
--a уменьшает переменную «a» до 2 и возвращает её
++a увеличивает переменную «a» до 3 и возвращает её
Получается:
2 + (2 * 3)
a++ возвращает 2 и увеличивает переменную «a» до 3.
--a уменьшает переменную «a» до 2 и возвращает её
++a увеличивает переменную «a» до 3 и возвращает её
Получается:
2 + (2 * 3)
+4
8? лень проверять
0
0
var a = 2, b = 0;
b = (a++ + (--a * ++a));
alert(b);
(0) a = 2; | b = (a++ + (--a * ++a));
(1.0) a = 3; | b = (2 + (--a * ++a));
(1.1) a = 2; | b = (2 + (2 * ++a));
(1.2) a = 3; | b = (2 + (2 * 3));
(2) b = 8;
b = (a++ + (--a * ++a));
alert(b);
(0) a = 2; | b = (a++ + (--a * ++a));
(1.0) a = 3; | b = (2 + (--a * ++a));
(1.1) a = 2; | b = (2 + (2 * ++a));
(1.2) a = 3; | b = (2 + (2 * 3));
(2) b = 8;
+10
У операторов сначала вычисляется левый операнд затем правый. Для ||, &&, например, это прямо влияет на вычисления следующего операнда.
+3
НЛО прилетело и опубликовало эту надпись здесь
Не унарная операция, а левый операнд бинарной операции, который, по счастливому совпадению, является инкрементом
+3
В данном случае, да. Извиняюсь, по короче. Представьте себе дерево разбора. В корне +, на левой ветви ++a, на правой (--a * ++a), у неё в свою очередь в корне *, на левой ветви --a, на правой ветви ++a, и т.д. Вычисления идут слева направо — сначала полностью посчитается левая ветвь, затем правая. (см. коммент skel2007 ниже)
Пример можно переписать так:
var a = 2, b = 0, c = 0;
b = ( (c = a, a = c+1, c) + ( (a = a-1, a) * (a = a+1, a) ) )
Пример можно переписать так:
var a = 2, b = 0, c = 0;
b = ( (c = a, a = c+1, c) + ( (a = a-1, a) * (a = a+1, a) ) )
0
8, проверил в браузере- 8… я удивлен^^
-1
т.е. не удивительно, что операция () выполняется позже инкремента?
-1
Правила, которым нас учили в первом классе, не работают. Вспомните перестановочность операции сложения.
А теперь посчитайте выражения
То же самое и с скобками. Не работает правило «что в скобках, то выполняется первым». Здесь скобки лишь указывают, что является операндом какой операции. И a здесь оказывается таким же выражением, обладающим теми же правами.
Если угодно, то объяснить можно так:
1) строится дерево выражения
2) запрашивается значение его вершины
3) при запросе значения любой вершины, соответствующей бинарному операнду, идет подзапрос на ЛЕВУЮ вершину, а после того, как получено ее значение, — подзапрос на ПРАВУЮ
В нашем случае дерево имеет вид:
Пользуясь вышеописанными правилами, вполне логично получаем 8.
А теперь посчитайте выражения
a + (++a * ++a)и
(++a * ++a) + aПерестановочность? Чушь.
То же самое и с скобками. Не работает правило «что в скобках, то выполняется первым». Здесь скобки лишь указывают, что является операндом какой операции. И a здесь оказывается таким же выражением, обладающим теми же правами.
Если угодно, то объяснить можно так:
1) строится дерево выражения
2) запрашивается значение его вершины
3) при запросе значения любой вершины, соответствующей бинарному операнду, идет подзапрос на ЛЕВУЮ вершину, а после того, как получено ее значение, — подзапрос на ПРАВУЮ
В нашем случае дерево имеет вид:
(Здесь через .++ и ++. обозначаются операции, соответствующие a++ и ++a).+ .++ * a --. ++. a a
Пользуясь вышеописанными правилами, вполне логично получаем 8.
+1
Правила, которым нас учили в первом классе, не работают. Вспомните перестановочность операции сложения.Не согласен, в этих примерах сложение принимает различные операнды, соответственно коммутативность не нарушается.
А теперь посчитайте выражения
a + (++a * ++a)
и
(++a * ++a) + a
Перестановочность? Чушь.
+1
алгебра не манипулирует переменными, а только константами.
0
Простите, но не интересная задачка… Все оказалось как и должно быть…
+4
задачка ради задачки… и точнее пудрения мозгов.
В разработке таких выражений не должно быть.
В разработке таких выражений не должно быть.
-2
1 * (1 + 1)
Скобки не означают, что сначала будет посчитано 1 + 1, они просто говорят, что 1 + 1 — это правый операнд умножения.
Хотя, может, в арабских компиляторах и справа налево считается;)
Скобки не означают, что сначала будет посчитано 1 + 1, они просто говорят, что 1 + 1 — это правый операнд умножения.
Хотя, может, в арабских компиляторах и справа налево считается;)
+3
Посчитал в уме — получилось 8. В комментариях увидел что так и есть.
В данном случае если скобки убрать должно получится тоже самое. И это правильно.
Скобки позволяют изменить привычный порядок, например
2+2*2 != (2+2)*2
В других случаях скобки роли не играют.
В данном случае если скобки убрать должно получится тоже самое. И это правильно.
Скобки позволяют изменить привычный порядок, например
2+2*2 != (2+2)*2
В других случаях скобки роли не играют.
0
«комментарии (42)» — Хабр как бы говорит нам :)
-2
В С++ для таких случаев есть специальное редкое правило «sequence point», которое определяет как работают операторы с side-effect'ом. К сожалению, джаву я знаю хуже и там их не встречал. Но вполне может быть что они там есть ^_^. Для C++ такой код был бы некорректен (скомпилился бы, но результат compiler specific), так как запрещено использовать в рамках одного sequence point оператор с side effect'ом ( a ++ ) и любой другой оператор, изменяющий значение этой же переменной. Гуру Java, как там в ней с такими изысками?
+1
> var a=2
> b=a++ + (--a * ++a)
> //Чему равно b?
1. Как это решает комп:
Для тех не в курсе дела, пусть посмотрят что такое обратная польcкая запись: ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D1%8C%D1%81%D0%BA%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D1%8C
Итак, расписываем псевдокод разбора выражения, согласно обратной польской записи:
1. встретили a, помещаем в стек операндов значение a
2. встретили ++, увеличиваем a на 1
3. встретили +, помещаем в стек операторов оператор +
4.…
Таким образом расписав, получается верный ответ (лень расписывать до конца на ночь глядя, довольно большой список получится)
2. Как это решает человек, который в читал спеки (человек-комп):
Унарные операторы имеют приоритет над всеми остальными операторами, и вычисляется по мере использования в выражении независимо от наличия скобок.
То есть, определив ход вычисления (что за чем вычисляется), сначала вычисляем унарные, потом — все остальное.
Получаем:
b = a++ + (--a * ++a) = [первый операнд=2, второй=(первый+1)-1, третий=второй+1] = 2+((2+1-1)*(2+1)) = 8
3. Как это решает человек логичный:
Первый ++ компенсируется последующим --, а последний ++ заменяется на a+1, и выражение упрощается:
b = a+a*(a+1) = 2+2*3 = 8
> b=a++ + (--a * ++a)
> //Чему равно b?
1. Как это решает комп:
Для тех не в курсе дела, пусть посмотрят что такое обратная польcкая запись: ru.wikipedia.org/wiki/%D0%9E%D0%B1%D1%80%D0%B0%D1%82%D0%BD%D0%B0%D1%8F_%D0%BF%D0%BE%D0%BB%D1%8C%D1%81%D0%BA%D0%B0%D1%8F_%D0%B7%D0%B0%D0%BF%D0%B8%D1%81%D1%8C
Итак, расписываем псевдокод разбора выражения, согласно обратной польской записи:
1. встретили a, помещаем в стек операндов значение a
2. встретили ++, увеличиваем a на 1
3. встретили +, помещаем в стек операторов оператор +
4.…
Таким образом расписав, получается верный ответ (лень расписывать до конца на ночь глядя, довольно большой список получится)
2. Как это решает человек, который в читал спеки (человек-комп):
Унарные операторы имеют приоритет над всеми остальными операторами, и вычисляется по мере использования в выражении независимо от наличия скобок.
То есть, определив ход вычисления (что за чем вычисляется), сначала вычисляем унарные, потом — все остальное.
Получаем:
b = a++ + (--a * ++a) = [первый операнд=2, второй=(первый+1)-1, третий=второй+1] = 2+((2+1-1)*(2+1)) = 8
3. Как это решает человек логичный:
Первый ++ компенсируется последующим --, а последний ++ заменяется на a+1, и выражение упрощается:
b = a+a*(a+1) = 2+2*3 = 8
+2
я решал так :)
> var a=2
> b=a++ + (--a * ++a)
> //Чему равно b?
сначала взял скобки (--a * ++a) и пошел справа на лево
2+1 = 3 * 2 = 6 -1 = 5, все что в скобках = 5
5++ = 6 + 2 = 8
итого получилось 8, а все от того, что почему то вспомнил правило, справа на лево :)
> var a=2
> b=a++ + (--a * ++a)
> //Чему равно b?
сначала взял скобки (--a * ++a) и пошел справа на лево
2+1 = 3 * 2 = 6 -1 = 5, все что в скобках = 5
5++ = 6 + 2 = 8
итого получилось 8, а все от того, что почему то вспомнил правило, справа на лево :)
-4
Сначала все выражение будет представлено как сумма двух подвыражений.
Из них первым будет вычислено левое, что даст 2, a станет равно 3.
Затем правое, что даст 2*3 = 6.
После этого они будут сложены, получим 2+6 = 8.
Из них первым будет вычислено левое, что даст 2, a станет равно 3.
Затем правое, что даст 2*3 = 6.
После этого они будут сложены, получим 2+6 = 8.
0
$ python
>>> a=2
>>> print a++ + (--a * ++a)
6
Как-то так.
-1
Исходя из приоритета операций скобки () имеют наивысший приоритетТут какая-то путаница.
Скобки — это не оператор и не операция, это явное изменение порядка выполнения.
Приоритеты служат для разбора порядка выполнения в неявном случае.
Если скобки не меняют порядок, то они не должны никак влиять на результат. То есть a+b*c и a+(b*c) должны выдавать одинаковый результат, что бы там под a,b и c не было.
0
НЛО прилетело и опубликовало эту надпись здесь
C и Javascript достаточно сильно различаются. Плюс, в C для указанного выше примера будет также действовать правило sequence points, которое в данной таблице на рассмотрено.
+1
НЛО прилетело и опубликовало эту надпись здесь
А как точки следования можно ПРИМЕНИТЬ? O_O
Я не гуру, но насколько я помню, точки следования влияют на то, что происходит МЕЖДУ ними. В данном случае конструкция как раз расположена между точками следования, соответственно внутри нее нельзя более одного раза менять значение 'a' операторами '++'/'--'.
Но это для C++, а у топикстартера Javascript. Как там с точками следования я не знаю, поверхностное гугление вскрывает только подобные вопросы 'фигли оно разное в сях и джаваскрипте' :(
Я не гуру, но насколько я помню, точки следования влияют на то, что происходит МЕЖДУ ними. В данном случае конструкция как раз расположена между точками следования, соответственно внутри нее нельзя более одного раза менять значение 'a' операторами '++'/'--'.
Но это для C++, а у топикстартера Javascript. Как там с точками следования я не знаю, поверхностное гугление вскрывает только подобные вопросы 'фигли оно разное в сях и джаваскрипте' :(
0
Данная таблица тут не применима. Обратите внимание, постфиксный инкремент по приоритету стоит ниже присваивания, а в рассматриваемом примере он выполняется первым.
0
НЛО прилетело и опубликовало эту надпись здесь
Приоритет выполнения операторов на PHP
php.net/manual/en/language.operators.precedence.php
php.net/manual/en/language.operators.precedence.php
0
Только я не понимаю смысл всех этих задач на приоритеты операций?
В целом-то задача тривиальная всегда: аккуратно разложить и посмотреть что будет — думать особо не надо.
Итак, вопрос: чего мы пытаемся добиться этими задачами?
В целом-то задача тривиальная всегда: аккуратно разложить и посмотреть что будет — думать особо не надо.
Итак, вопрос: чего мы пытаемся добиться этими задачами?
+1
Зарегистрируйтесь на Хабре, чтобы оставить комментарий
Интересная задачка