2013-01-02 19 views
8

Nel manuale di PHP, operator precedence section, c'è questo esempio:

// mixing ++ and + produces undefined behavior 
$a = 1; 
echo ++$a + $a++; // may print 4 or 5 

capisco il comportamento è indefinito a causa del seguente motivo:

Dal x + y = y + x l'interprete è libero di valutare x e per l'aggiunta in qualsiasi ordine al fine di ottimizzare la velocità e/o la memoria. Ho concluso questo dopo aver visto il C code example in this article.

La mia domanda è che l'uscita del codice PHP di cui sopra dovrebbe essere 4 non importa in che modo l'espressione e la sub-espressioni vengono valutate:

  • op1 = ++ $ a => $ a = 2 , op1 = 2; op2 = $ a ++ => op2 = 2, $ a = 3; 2 + 2 = 4
  • op1 = $ a ++ => op1 = 1, $ a = 2; op2 = ++ $ a => op2 = 3, $ a = 3; 1 + 3 = 4

Da dove viene il 5? O dovrei saperne di più su come funzionano gli operatori?

Edit:

Sono stato fissando Incrementing/Decrementing Operators sezione, ma ancora non riuscivo a capire perché 5.

++ $ a: pre-incremento - Incrementi $ a di una, quindi restituisce $ a.
$ a ++: post-incremento - restituisce $ a, quindi incrementi $ uno alla volta.

+0

Hai davvero ottenuto 5 stampati durante l'esecuzione di questo codice? – Ranty

+0

No. Ho sempre avuto 4 con alcune versioni di PHP. È la parola _may_, significa che potrei eseguire questo codice un milione di volte ottenendo il risultato 4 ma non c'è _garantito_. –

+0

@ H2CO3: Sono più interessato a conoscere _why 5_. –

risposta

5
a = 1; 
++ (preincrement) gives a = 2 (higher precedence than +, and LR higher precedence than postincrement) 
++ (postincrement) gives a = 3 (higher precedence than +) 
+ (add) gives 2 + 3 = 5 

$ una è inizialmente impostato su 1. Il ++ $ a poi preincrements $ una prima di utilizzarlo nella formula, impostandola 2, e spingendo tale valore nello stack lexer. Il $ ++ viene quindi eseguito, poiché l'incrementatore ha una precedenza più alta di +, e tale valore viene anche inserito quel risultato nello stack del lexer; e l'aggiunta che ha luogo aggiunge il risultato 2 della pila del lexer al risultato 3 della pila del lexer dando un risultato di 5, che viene poi echeggiato. Il valore di $ una volta che la linea è eseguito è 3.

O

a = 1; 
++ (preincrement) gives a = 2 (higher precedence than +, and LR higher precedence than postincrement) 
+ (add) gives 2 + 2 = 4 (the value that is echoed) 
++ (postincrement) gives a = 3 (incremented __after__ the variable is echoed) 

$ una è inizialmente impostato su 1. Quando la formula è analizza i ++ $ a preincrements $ a, impostandolo su 2 prima di usarlo nella formula (premendo il risultato sullo stack lessico). Il risultato dalla pila del lexer e il valore corrente di $ a vengono quindi aggiunti insieme dando 4; e questo valore è echeggiato. Infine, $ a è postincrementato, lasciando un valore di 3 in $ a.

+2

Ho modificato la mia domanda. Avevo pensato anche a questo, ma in seguito mi sono reso conto che l'incremento post restituirà il valore corrente (cioè 2), _ poi l'incremento a. –

1

Sì, questo vi darà 5 perché l'operatore di destra opera prima per priorità/precendente e dopo questo l'operatore somma (+) funzionerà. Quindi primo incremento rende a 2 e seconda rende a 3 e dopo che sia sommerà e uscite il risultato come 5

$result = ++$a + $a++; 

++$a uscite come 2

$a++ uscite come 2 3 solo ma internamente sarà incrementato.

finalmente somma sarà accade come 2 + 3 = 5

+2

"Sì, ti darà 5" - piuttosto "Sì, potrebbe anche darti 5". –

+0

Anche se $ a è 3 dopo aver valutato $ a ++, l'espressione $ a ++ continua a valutare 2, quindi la somma è 2 + 2. – fgb

0

Mark, credo che vi sbagliate!

Post-incremento: restituisce $ a, quindi incrementa $ a uno a uno. (dalla documentazione)

Quindi non c'è modo di ottenere $ un valore di 3 in somma.

+0

Il punto è che il risultato è imprevedibile: OP chiedeva come fosse possibile ottenere un risultato di 5, non se avesse dato un risultato di 5 –

+0

Ma poi una spiegazione: "++ $ a dà 0 e $ a ++ dà 5, quindi 0 + 5 = 5 "darebbe lo stesso sforzo. Voglio dire, entrambi sono contro la documentazione. – TomTom