2014-09-22 2 views
4

Что такое precidency и associtivity для оператора инкремента и оператора присваивания для блока кодаЧто такое precidency и associtivity для оператора инкремента и оператора присваивания для блока кода

$a=array(1,2,3); 
$b=array(4,5,6); 
$c=1; 

$a[$c++]=$b[$c++]; 

print_r($a); 

В соответствии с исполнением его выдает

Array 
     ( 
     [0] => 1 
     [1] => 6 
     [2] => 3 
     ) 

Но я не могу понять, как массив $a индекс 1 содержит значение массива $b индекса 2 значения. Может ли кто-нибудь объяснить сценарий, как происходит выполнение?

+0

Не является ли это случай * непредсказуемое поведение *? См. Http://stackoverflow.com/questions/949433/why-are-these-constructs-undefined-behavior?lq=1. – SukkoPera

+0

Можете ли вы объяснить, что именно вас озадачивает в этом поведении? Это поведение «++» или порядок выполнения? Какой результат вы ожидали бы? – deceze

+0

Привет, Deceze наиболее озадачивающим является то, какой шаг стороне стороны должны быть рассчитаны в первую очередь? Но в соответствии с таблицей приоритета оператор приращения имеет правую ассоциативность. Поэтому в вопросе в четвертой строке $ C++ в правой части оператора присваивания должен выполняться сначала i.e. Сначала нужно выполнить $ b [$ C++]. – bikashphp

ответ

0

В ++пост оператор приращение первые возвращает значение, а затем (запись) увеличивает значение. То есть $c++ возвращает значение $c, , затем прирост $c.

Это то, очевидно, выполняет так:

$a[$c++] = 

Здесь значение $c++ принимается 1, но $c затем после увеличивается до 2.

$b[$c++] 

Здесь значение $c++ берется 2, а затем $c пост-увеличивается до 3 (который никто не заботится о больше, хотя).

Таким образом, выражение эквивалентно:

$a[1] = $b[2]; 

Для Напротив, предварительно Приращения оператора++$varпервого увеличивает значение, а затем возвращает новое увеличенное значение. Таким образом, $a[++$c] = $b[++$c] приведет к Неопределенное смещение 3 в $b ошибка.

+0

Но присваивание имеет правую ассоциативность, почему $ с ++ подсчитали слева? – sectus

+0

Логическая ассоциативность и порядок оценки не обязательно одно и то же. Ассоциативность относится к * как * два операнда будут добавляться вместе, а не * когда * оценивается * выражение * операнда *. – deceze

+0

Привет, дезинфекция в соответствии с вашей защитой, что такое логическая ассоциативность? Тогда, если есть такое понятие, то каково понятие левой и правой и правой к левой ассоциативности при вычислении операции? – bikashphp

2

PHP (еще раз) отличается от других языков тем, что осталось часть присваивания оценивается в первую очередь. Простое доказательство:

$a[print 1] = $b[print 2]; // what does this print? 

Согласно http://3v4l.org/, этот код:

$a = array(); $b = array(); $c = 1; 
$a[$c++]=$b[$c++]; 

сгенерированные следующие опкоды:

compiled vars: !0 = $a, !1 = $b, !2 = $c 
line  # * op       fetch   ext return operands 
--------------------------------------------------------------------------------- 
    2  0 > INIT_ARRAY          ~0  
     1  ASSIGN             !0, ~0 
     2  INIT_ARRAY          ~2  
     3  ASSIGN             !1, ~2 
     4  ASSIGN             !2, 1 
    3  5  POST_INC           ~5  !2 
     6  POST_INC           ~7  !2 
     7  FETCH_DIM_R          $8  !1, ~7 
     8  ASSIGN_DIM            !0, ~5 
     9  OP_DATA             $8, $9 
     10 > RETURN             1 

Опкод 5 является оставил$c++ и опкод 6 $c++. Таким образом, окончательное присваивание (опкод 8) оцениваются как

$a[1] = $b[2]; 

, что приводит к (1,6,3).

0

Это называется неопределенным порядком оценки.

Приоритет и ассоциативность операторов определяют, как сгруппированы выражения , они не определяют порядок оценки. PHP не (в общем случае) укажите, в каком порядке вычисляется выражение , и код, который предполагает определенный порядок оценки, следует избегать , поскольку поведение может изменяться между версиями PHP или в зависимости от окружающего кода.

http://php.net/manual/en/language.operators.precedence.php#example-130

Но нынешнее поведение никогда не изменились: http://3v4l.org/b1Y1X