2015-04-01 12 views
5

nie jestem w stanie pojąć logikę oceny w kodzie podanym poniżej. Czy ktokolwiek wie, dlaczego PHP ocenia inaczej $b i $b = $b w tym przypadku?

Czytałem poprzez liczne pytania tutaj na SO i sprawdził PHP manual. Czyniąc to Doszedłem do zrozumienia, że ​​„PHP nie robi (w ogólnym przypadku) określić, w jakiej kolejności wyrazem jest oceniany” i że „zachowanie może zmienić między wersjami PHP, lub w zależności od otaczającego kodem” . Nie sądzę jednak, aby miało to zastosowanie do tej sytuacji. Czy to prawda?

Jako pierwszy przyznać się do tego nie może być codziennego problem kodowania, wciąż jestem ciekawy. Natknąłem się na to, próbując zrobić jakieś code golfing.

$a = [[00, 01, 02, 03], 
     [10, 11, 12, 13], 
     [20, 21, 22, 23], 
     [30, 31, 32, 33]]; 

$b = 2; 
echo $a[$b][$b++], PHP_EOL; 

$b = 2; 
echo $a[$b=$b][$b++], PHP_EOL; 

Wyjście - PHP 5.5.14:

32 
22 
+0

Co php mówi, że nie gwarantuje porządku jak matematyczny porządek operacji. Może mieć taką samą kolejność w każdej aktualnej wersji i systemie i działać dokładnie tak samo. Mówią, że zmiana w późniejszej wersji może zmienić wynik i nie gwarantują, że zawsze będzie działać tak samo. –

Odpowiedz

10

To wygląda na przykład w manual wykorzystywane do wykazania Niezdefiniowany kolejność oceny. Z instrukcji:

Priorytety operatorów i ich łączność określają tylko sposób grupowania wyrażeń, nie określają kolejności oceny. PHP nie (w ogólnym przypadku) określić, w jakiej kolejności wyrazem jest oceniany i kod, który zakłada konkretną kolejność oceny powinny być unikane, ponieważ zachowanie może zmienić między wersjami PHP, lub w zależności od otaczającego kodu.

Podkreślenie

Przykład dają:

<?php 
$a = 1; 
echo $a + $a++; // may print either 2 or 3 

$i = 1; 
$array[$i] = $i++; // may set either index 1 or 2 
?> 

otrzymujesz wyjście jesteś, bo w pierwszym przykładzie, indeks $b++ jest określana pierwszy, natomiast w drugim indeks pierwszy: $b=$b.

NB

chodzi o dlaczego to jest, moim zdaniem jeden z możliwych powodów jest wyjaśnione przez niniejszej noty na tej samej stronie podręcznika:

Chociaż = ma niższy priorytet niż większość innych operatory, PHP nadal zezwala na wyrażenia podobne do następujących: if (! $ a = foo()), w którym to przypadku zwracana wartość foo() jest umieszczana w $ a.

wierzę, że brakuje kluczową ostatnie słowo tam: pierwszy (bez, do mnie czyta notatkę traci trochę znaczenia).

Zgodnie z własnymi zasadami PHP, i przyjmujemy zlecenie FIFO, najpierw należy ocenić !$a.Jeśli $a jest obecnie null lub undefined, to !$a będzie równe true (zostanie ocenione, a wynik zostanie odrzucony). Następnie zostanie oszacowany foo(), a jego wartość zwracana zostanie przypisana do $a (nawet jeśli przyjmujemy FIFO, foo() musi być najpierw ocenione, jeśli jej wynik ma zostać przypisany do czegoś). Wynik tego zadania zostanie oceniony przez if i da dokładnie odwrotną wartość, jakiej poszukiwał autor.

nie jestem ekspertem C, ale trochę poszukiwań również prowadzić mi ten answer który cytuje standard C90:

(C90, 6,3) „O ile nie wskazano składni lub później (inaczej dla operatora funkcja-call(), & &, ||,:., a operatorzy przecinek) kolejności oceny podwyrażeń i kolejność, w której odbywają się skutki uboczne są zarówno unspecitied”

Ponieważ PHP jest zbudowany na C, ma sens, że odziedziczyłby część jego ecc entricities.

+0

Więc używanie "$ b ++" i '$ b' na tej samej linii jest jak przysłowiowe pudełko czekoladek. – developerwjk

+0

@developerwjk: Haha :-P Będę o tym pamiętać. – mhall

+0

Myślałem, że PHP może uznać '$ b' i' $ b = $ b' za równoważny, tak jak zoptymalizowałoby to głupie zadanie, ale myślę, że tak nie jest. – mhall

Powiązane problemy