Объяснение массивов и оператора ++ по индексу и значению - PullRequest
0 голосов
/ 26 марта 2019

Я изучал приоритет операторов в php7.2, когда выполнял этот код:

$i = 1;
$a[$i] = $i++;

var_dump($a);

$j = 1;
$b[$j++] = $j++;

var_dump($b);

И я получаю такой результат:

array(1) {
  [2]=>
  int(1)
}
array(1) {
  [1]=>
  int(2)
}

Я не понимаю, почему этот код дает эти выводы. Я мог бы получить первый var_dump, но второй кажется мне действительно странным.

Не могли бы вы объяснить, как эти два примера интерпретируются php шаг за шагом?

Я не получаю такие же результаты на php 4.

Ответы [ 3 ]

2 голосов
/ 26 марта 2019

Вместо того, чтобы отвечать, как другие люди, которые даже не знают, о чем говорят, без тестирования / поиска, вот начало отладки способа анализа PHP при преобразовании в byteCode.

https://derickrethans.nl/projects.html#vld

У меня недостаточно времени, чтобы сделать это самому.

Удачи!

1 голос
/ 27 марта 2019

Даже если C ++ является языком времени компиляции, стандартного поведения для инструкций, таких как x = x++, не существует, и результат различается для разных компиляторов.

PHP предварительно скомпилирован во время выполнения и, таким образом, оптимизирован по производительности с точки зрения времени компиляции. и время выполнения.Поведение не определено и может отличаться от версии к версии.

Таким образом, вы никогда не должны полагаться на конструкции внутри одной инструкции - ни на одном языке, кроме случаев, когда это было четко определено в ее спецификациях.

1 голос
/ 27 марта 2019

Я понял, все дело в приоритете операторов.

Операторы обрабатываются в следующем порядке:

  1. [
  2. ++ (отслева направо)
  3. =

В этих шагах интерпретируется следующий код:

$i = 1;
$a[$i] = $i++;
  1. $ i ++ возвращает 1 и затем увеличивается
  2. $ a [$ i] выделяется с $ i === 2
  3. $ a [2] присваивается с возвращаемым значением шага 1. поэтому $ a [2]=== 1

И с этим кодом:

$j = 1;
$b[$j++] = $j++;
  1. Левый $ j ++ возвращает 1, а $ j увеличивается
  2. Право$ j ++ возвращает 2 (потому что он был увеличен на шаге 1), а $ j снова увеличивается.На этом этапе $ j === 3
  3. $ b [1] выделяется, потому что первый шаг возвращает 1.
  4. $ b [1] присваивается возвращаемое значение шага2. Итак, $ b [1] === 2

Итак, последний пример делает почти то же самое, что и этот:

function incrementInteger(int &$i): int
{
    ++$i;
    return $i - 1;
}

$j = 1;
$b[incrementInteger($j)] = incrementInteger($j);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...