programacion - switch php sintaxis
¿Por qué $ a+++ $ a== 2? (13)
Si pruebo esto:
$a = 0;
echo $a + ++$a, PHP_EOL;
echo $a;
Obtengo esta salida:
2
1
Demostración: http://codepad.org/ncVuJtJu
¿Porqué es eso?
Espero obtener esto como un resultado:
1
1
Mi entendimiento:
$a = 0; // a === 0
echo $a + ++$a, PHP_EOL; // (0) + (0+1) === 1
echo $a; // a === 1
Pero, ¿por qué no es esa la salida?
Como sabrá, tenemos dos operadores de incrementos, uno es preincremento y el segundo es postincremento. El incremento previo aumenta el valor del número entero antes de usarlo en la expresión, por otro lado aumenta el valor del incremento del número después de usarlo en la expresión.
supongamos que tiene la variable $ a y la variable $ b como se muestra a continuación
$ a = 0;
$ b = ++ $ a da el valor de b = 1
mientras
$ b = $ a ++ da el valor b = 0
Como se mencionó anteriormente, hay una diferencia en x ++ y ++ x. Puedes interpretarlo de la manera que
x++;
incrementos después del punto y coma
y
++x;
incrementos en la evaluación de la expresión
Parece que tu expresión se evalúa de derecha a izquierda
echo $l + ++$l;
- Obtener $ l: $ l = 0
- Aplicar ++: ++ $ l = 1
- Obtener $ l: $ l = 1
- Aplicar +: $ l + $ l = 1 + 1 = 2
Cuando hagas tu ++ $ l (preincremento), se hará antes de tu adición -> verifica la precedencia del operador ).
Entonces, el valor de $l
será 1
antes de su adición:
echo $l + ++$l; // $l => 1 because ++$l is done first
Entonces tu respuesta será 2.
Pero cuando lo haces:
echo $l // you will get your first value which is $l => 1
Entonces tu respuesta será 1.
Este comportamiento puede confirmarse inspeccionando cómo PHP compila su script, por ejemplo:
$a = 0;
echo $a + ++$a;
Compila los siguientes códigos de operación, que luego se ejecutan:
compiled vars: !0 = $a
line # * op fetch ext return operands
---------------------------------------------------------------------------------
1 0 > ASSIGN !0, 0
1 PRE_INC $1 !0
2 ADD ~2 !0, $1
3 ECHO ~2
4 > RETURN null
Esto se traduce en el siguiente script equivalente:
$a = 0; // ASSIGN
$tmp = ++$a; // PRE_INC
echo $a + $tmp; // ADD, ECHO
Conclusión
Para cuando $a
se evalúa como la expresión de la mano izquierda de $a + (++$a)
, ya se ha incrementado, porque ++$a
se evaluó primero.
Obviamente, no se debe confiar en este comportamiento; en cualquier idioma para ese asunto.
La primera parte obvia es que ++
tiene mayor prioridad que +
.
La segunda parte es que el motor php no almacena el valor del primer operando en otra variable anónima. Entonces $l + ++$l
no es un qeuivalent para
$a = $l;
$b = ++$l;
return $a + $b;
La salida de tu código varía con la versión de PHP como se ve aquí
Salida para 4.3.0 - 5.0.5
1
1
En el caso anterior, se evalúa primero el lado izquierdo del operador +
(0, 1, +).
Salida para 5.1.0 - 5.5.0alpha4
2
1
En el caso anterior, el lado derecho del operador +
se evalúa primero (1, 1, +).
Esto está de acuerdo con la respuesta de Interjay de que en PHP no hay garantía sobre el orden de evaluación de las subexpresiones. La suposición de que la salida podría ser 1, 1
es correcta, así son las respuestas que afirman que la salida podría ser 1, 2
.
Mi orden de evaluación en una publicación de blog de PHP explica esto en detalle, pero esta es la idea básica:
- La precedencia del operador y la asociatividad no tienen nada que ver con el orden de evaluación.
- PHP no garantiza una orden de evaluación. El pedido puede cambiar entre versiones de PHP sin previo aviso y también puede ser diferente dependiendo del código que lo rodea.
- "Normalmente" PHP evaluará de izquierda a derecha, con la excepción de los accesos a variables "simples" (como
$a
). Los accesos a variables simples se ejecutarán después de expresiones más complejas, independientemente del orden en que se produzcan las expresiones. - En este caso particular, significa que
++$a
se ejecuta primero porque es una expresión compleja y solo entonces se recupera el valor de$a
(ya es 1 en este punto). Así que de manera efectiva estás sumando1 + 1 = 2
. - La razón por la que las variables simples se obtienen después de expresiones complejas es la optimización de variables compiladas (CV). Si deshabilita esta optimización, por ejemplo, mediante el uso del operador
@
supresión de errores, todas las expresiones se evalúan de izquierda a derecha, incluidas las simples extracciones de variables. - En este caso particular, significa que
@($a + ++$a)
dará como resultado1
, porque se obtiene primero$a
(0 en ese momento) y se incrementa solo después de eso.
Todas las declaraciones se ejecutan de derecha a izquierda. Entonces el valor se incrementa primero que el valor de tu variable es = 1, entonces 1 + 1 = 2
Todas las respuestas que explican por qué obtienes 2 y no 1 están realmente mal. De acuerdo con la documentación de PHP, mezclar +
y ++
de esta manera es un comportamiento indefinido, por lo que podrías obtener 1 o 2. Cambiar a una versión diferente de PHP puede cambiar el resultado que obtienes, y sería igual de válido.
Vea el ejemplo 1 , que dice:
// mixing ++ and + produces undefined behavior
$a = 1;
echo ++$a + $a++; // may print 4 or 5
Notas:
La precedencia del operador no determina el orden de la evaluación. La precedencia del operador solo determina que la expresión
$l + ++$l
se analiza como$l + (++$l)
, pero no determina si el operando izquierdo o derecho del operador+
se evalúa primero. Si el operando de la izquierda se evalúa primero, el resultado sería 0 + 1, y si el operando de la derecha se evalúa primero, el resultado sería 1 + 1.La asociatividad del operador tampoco determina el orden de evaluación. Que el operador
+
haya dejado la asociatividad solo determina que$a+$b+$c
se evalúa como($a+$b)+$c
. No determina en qué orden se evalúan los operandos de un único operador.
También relevante: en este informe de error con respecto a otra expresión con resultados indefinidos, un desarrollador de PHP dice: "No garantizamos el orden de la evaluación [...], como C no lo hace. ¿Puede señalar cualquier lugar en el documentación donde se indica que el primer operando se evalúa primero? "
Un operador preincremento "++" tiene lugar antes de que el resto de la expresión esté en evaluación. Entonces es en realidad:
echo $l + ++$l; // (1) + (0+1) === 2
Verifique el incremento del manual del operador:
http://www.php.net/manual/en/language.operators.increment.php
O vea este teclado: http://codepad.org/Y3CnhiLx
<?php
$n = 0;
$m = 0;
echo ''++ before:'';
echo $n+ ++$n;
echo PHP_EOL;
echo ''++ after:'';
echo $m+ $m++;
echo PHP_EOL;
echo ''n:''.$n;
echo PHP_EOL;
echo ''m:''.$m;
Productos:
++ before:2
++ after:1
n:1
m:1
++
es el operador de mayor precedencia, por lo que se aplica primero.
Entonces ahora l = 1.
Entonces 1 + 1 = 2.
a + b
a = 1
b = ++a
:= 2
¿Por qué esperas algo más?
En PHP:
$a = 0;
$c = $a + ++$a;
Precedente del operador visualizado:
$c = ($a) + (++$a);
Secuencia de evaluación visualizada:
$a = 0; ($a = 0)
$a = 1; (++$a)
$c = $a + $a (1 + 1);
O escrito:
En el momento en que se realiza la operación de suma, $a
ya es 1 porque ++$a
ya ha sido evaluado. El operador ++
se evalúa antes que el operador +
.
Para la diversión:
$a++ + ++$a
Resultados en 2, también. Sin embargo, si lo compara como una expresión, no es igual:
$a++ + ++$a == $a + ++$a
Donde como
$a++ + ++$a == $a-- + --$a
es igual".
Ver también: