【问题标题】:What is the precidency and associtivity for increment operator and assignment operator for the block of code代码块的增量运算符和赋值运算符的总裁和关联性是什么
【发布时间】:2014-09-22 09:09:42
【问题描述】:

代码块的增量运算符和赋值运算符的精确性和关联性是什么

$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 的值。谁能解释一下执行是如何发生的场景?

【问题讨论】:

  • 这不是未定义行为的情况吗?见stackoverflow.com/questions/949433/…
  • 您能否澄清一下您对这种行为的困惑究竟是什么?是++的行为还是执行顺序?你会期待什么结果?
  • 嗨 deceze 最令人困惑的是应该先计算哪一侧的帖子增量?但是根据优先表,增量运算符具有正确的关联性。所以在第四行的问题中,赋值运算符右侧的 $c++ 应该首先执行,即 $b[$c++] 应该首先执行。

标签: php operator-precedence associativity


【解决方案1】:

PHP (再次)与其他语言的不同之处在于赋值的 left 部分首先计算。简单证明:

$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 是 left $c++,操作码 6 是 right $c++。所以最终的赋值(操作码 8)被评估为

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

导致(1,6,3)

【讨论】:

    【解决方案2】:

    ++后递增运算符首先返回值,然后(后)递增值。 IE。 $c++ 返回$c 的值,然后递增$c

    然后显然是这样执行的:

    $a[$c++] =
    

    这里$c++ 的值被取为1,但$c 然后后递增到2

    $b[$c++]
    

    这里$c++ 的值被取为2,然后$c 被后递增到3(虽然没人关心了)。

    所以表达式等价于:

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

    相比之下,预增量运算符 ++$var first 递增值,then 返回新的递增值。所以$a[++$c] = $b[++$c] 将导致$b 中的未定义偏移量3 错误。

    【讨论】:

    • 但是赋值有右结合性,为什么$с++要从左数呢?
    • 逻辑关联性和评估顺序不一定是一回事。关联性是指如何将两个操作数相加,而不是何时计算任一操作数的表达式
    • 嗨 deceze 根据您的定义,什么是逻辑关联?那么如果有这样的概念,那么计算运算时从左到右和从右到左的关联性是什么概念?
    • @bika 在这种情况下,运算符之间的关联性仅表明右侧的整体将分配给左侧的单个变量;即$a = $b + $c + $d 表示$b + $c + $d 将被分配给$a,而不可能是($a = $b + $c) + $d。与此无关的是每个操作数的评估顺序,即没有定义在分配发生之前调用所有这些函数的顺序:$a[foo(bar())] = baz(blarg())
    【解决方案3】:

    这称为未定义的评估顺序。

    运算符优先级和关联性仅决定表达式的方式 是分组的,它们没有指定评估顺序。 PHP 没有 (在一般情况下)指定表达式的顺序 评估和假定特定评估顺序的代码应该 应避免,因为行为可能会在 PHP 版本或 取决于周围的代码。

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

    但当前行为从未改变:http://3v4l.org/b1Y1X

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-25
      • 2013-07-08
      • 2011-11-16
      • 2013-06-28
      • 1970-01-01
      • 2011-01-23
      相关资源
      最近更新 更多