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

159
18 июля 2017, 20:41
<?php
$b=10;
$f=$b + $b + --$b;
echo $f;  //выведет 29, вроде правильно
$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)

Answer 1

Очень интересный приоритет операторов у этого вашего PHP. К тому же сложение выполняется по порядку, но слагаемые вычисляются наоборот справа налево в данном случае. Этот порядок не гарантируется, поэтому результат на других версиях PHP может отличаться. К примеру на версии 5.0.4 порядок тот же, но слагаемые вычисляются более привычно слева направо, см. UPD.

Уравнение первое $f=$b + $b + --$b;

  1. Складываем $b + $b и запоминаем результат $temp = 20.
  2. Справа инкремент, выполняем его и складываем с левым значением $temp.
  3. 20 + 9 = 29.

Уравнение второе $f = $b + --$b;

  1. Справа инкремент, выполняем его и получаем 9.
  2. Слева ссылка на $b, раскрываем ее и там у нас лежит после инкремента девятка.
  3. 9 + 9 = 18.

Уравнение третье $f=$b + $b + $b--;

  1. Складываем $b + $b и запоминаем результат $temp = 20.
  2. Справа преинкремент, выполняем его возвращая 10 и складываем с левым значением $temp.
  3. 20 + 10 = 30

Уравнение четвертое $f=$b + $b--;

  1. Слева инкремент, выполняем его возвращая 10 и складываем с левым значением.
  2. Слева ссылка, раскрываем ее и получаем 9.
  3. 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;

  1. Складываем $b + $b и запоминаем результат $temp = 20.
  2. Складываем с левым значением $temp полученный инкремент.
  3. 20 + 9 = 29.

Уравнение второе $f = $b + --$b;

  1. Слева ссылка на $b, раскрываем ее и получаем 10.
  2. Справа инкремент, выполняем его и получаем 9.
  3. 10 + 9 = 19.

Уравнение третье $f=$b + $b + $b--;

  1. Складываем $b + $b и запоминаем результат $temp = 20.
  2. Складываем с левым значением $temp преинкремент 10.
  3. 20 + 10 = 30

Уравнение четвертое $f=$b + $b--;

  1. Слева ссылка, раскрываем ее и получаем 10.
  2. Слева инкремент, выполняем его возвращая 10 и складываем с левым значением.
  3. 10 + 10 = 20.
READ ALSO
Цикл загружает страницу php

Цикл загружает страницу php

Есть файл с таким кодом

184
STEAM API | Проверка аккаунта на наличие игры

STEAM API | Проверка аккаунта на наличие игры

Как используя steam api проверить аккаунт на наличие csgo?

199
Почему цикл останавливается?

Почему цикл останавливается?

код получает только json объект 1 раз, по элементу нулевого массиваостальные 2 он не запрашивает вообще

166
Как запретить доступ на просмотр файла php?

Как запретить доступ на просмотр файла php?

Надо запретить доступ на просмотр нескольких файлов (их может быть тысячи)Например: header

254