Страницы

Поиск по вопросам

понедельник, 18 февраля 2019 г.

Странное поведение оператора — в PHP

$b=10; $f=$b + --$b; echo $f; //выведет 18, почему не 19 !?!?!?
//или еще вот так $b=10; $f=$b + $b + $b--; echo $f; //выведет 30, ожидаемо, но, смотрим дальше
$b=10; $f=$b + $b--; echo $f; //выведет...пауза...затаили дыхание...барабанный бой...19!!!!
Буду очень признателен, если кто-нибудь сможет объяснить, почему так происходит. Версия PHP 7.1.6 (xampp v3.2.2)


Ответ

Очень интересный приоритет операторов у этого вашего PHP. К тому же сложение выполняется по порядку, но слагаемые вычисляются наоборот справа налево в данном случае. Этот порядок не гарантируется, поэтому результат на других версиях PHP может отличаться. К примеру на версии 5.0.4 порядок тот же, но слагаемые вычисляются более привычно слева направо, см. UPD.
Уравнение первое $f=$b + $b + --$b;
Складываем $b + $b и запоминаем результат $temp = 20. Справа инкремент, выполняем его и складываем с левым значением $temp. 20 + 9 = 29.
Уравнение второе $f = $b + --$b;
Справа инкремент, выполняем его и получаем 9. Слева ссылка на $b, раскрываем ее и там у нас лежит после инкремента девятка. 9 + 9 = 18.
Уравнение третье $f=$b + $b + $b--;
Складываем $b + $b и запоминаем результат $temp = 20. Справа преинкремент, выполняем его возвращая 10 и складываем с левым значением $temp. 20 + 10 = 30
Уравнение четвертое $f=$b + $b--;
Слева инкремент, выполняем его возвращая 10 и складываем с левым значением. Слева ссылка, раскрываем ее и получаем 9. 9 + 10 = 19.
Но гораздо веселее складывать такое: $f=$b + $b + $b-- + $b + $b; и $f=$b + $b + --$b + $b + $b;
P.S. Лучше избегайте таких конструкций, результат которых может быть неопределенным и никак не гарантируется разработчиками.
UPD.. На версии 5.0.4 порядок тот же, но слагаемые вычисляются более привычно слева направо. Поэтому в примерах выше сначала раскроются ссылки слева и потом будет вычислен инкремент справа.
Уравнение первое $f=$b + $b + --$b;
Складываем $b + $b и запоминаем результат $temp = 20. Складываем с левым значением $temp полученный инкремент. 20 + 9 = 29.
Уравнение второе $f = $b + --$b;
Слева ссылка на $b, раскрываем ее и получаем 10. Справа инкремент, выполняем его и получаем 9. 10 + 9 = 19.
Уравнение третье $f=$b + $b + $b--;
Складываем $b + $b и запоминаем результат $temp = 20. Складываем с левым значением $temp преинкремент 10. 20 + 10 = 30
Уравнение четвертое $f=$b + $b--;
Слева ссылка, раскрываем ее и получаем 10. Слева инкремент, выполняем его возвращая 10 и складываем с левым значением. 10 + 10 = 20.

Комментариев нет:

Отправить комментарий