Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: porównanie zmiennej do 0 w if() / else if() oraz switch() - różnice, gdy zmienna = 0
Forum PHP.pl > Forum > Przedszkole
blooregard
Witam,

Naprawdę zgłupiałem. Albo o czymś nie wiem.

Mam w programie taki test, gdzie zmienna może przyjąć trzy wartości: mniejszą od zera, większą od zera bądź zero.
Żeby nie jechać trzy razy if / else if / else if napisałem swich(), który w zależności od wartości zmiennej podejmuje odpowiednie działania.
W case() sprawdzam po kolei wystąpienie wszystkich warunków:
case ($a < 0) ... bla bla rób to; break;
case ($a > 0) ... bla bla rób tamto; break;
case ($a == 0) ... bla bla siamto; break;
Moja radośc trwała do momentu, gdy zmienna $a przyjęła wartość 0, a wkonał się kod zawarty w teście case($a < 0).
Myślę sobie, qrde, co jest, od kiedy 0 jest mniejsze od 0 ?
No i zaczęła się walka.
Ustawiałem warunki w różnej kolejności, eliminowałem warunek case ($a == 0), wtedy i tak wykonywał się kod zawarty w case ($a < 0),
rzutowałem $a na wszelkie możliwe intval-e , integery itp. , porównywałem ją w taki sposób: case ($a === 0).
Nic.
Uprzedzając wszelkie pytania: nie ma błędów w składni, wszędzie są brejki itd.

Z problemem zetknąłem się w większej aplikacji, ale dla porównania napisałem sobie ten test:
  1. <?php
  2. //$a = -1;
  3. $a = 0;
  4. //$a = 1;
  5.  
  6. echo '$a = '.$a;
  7.  
  8. echo '<br />w switch(): a ';
  9. switch ($a) {
  10.    case ($a == 0): echo ' = 0'; break;
  11.    case ($a < 0): echo ' < 0'; break;
  12.    case ($a > 0): echo ' > 0'; break;
  13. }//switch
  14.  
  15. echo '<br />w if() / else if() / else if() : a ';
  16. if ($a == 0) {
  17.    echo ' = 0';
  18. } else if ($a < 0) {
  19.    echo '< 0';
  20. } else if ($a > 0) {
  21.    echo '> 0';
  22. }//if
  23. ?>


Teraz, gdy uruchamiam go sobie po kolei dla każdej wartości $a, mam następujące wyniki:
Kod
$a = -1
w switch(): a < 0
w if() / else if() / else if() : a < 0


Kod
$a = 1
w switch(): a > 0
w if() / else if() / else if() : a > 0


A teraz uwaga: dla $a = 0:
Kod
$a = 0
w switch(): a < 0
w if() / else if() / else if() : a = 0


WTF ?
wookieb
Kod
switch ($a) {
   case 0: echo ' = 0'; break;
   case ($a < 0): echo ' < 0'; break;
   case ($a > 0): echo ' > 0'; break;
}
blooregard
Tak, tak jest ok.
Ale wytłumacz mi proszę, czemu w case( $a == 0) dla $a = 0 NIE JEST prawdziwy ?
To mnie intryguje.
wookieb
Switch sprawdza to co podales mu w argumencie

Wiec rozpatrzmy twoje przypadki
Kod
$a=-1; //po konwersji true
//wiec
true==($a==0) // false
true==($a<0) // true
true==($a>0) // false


$a=1; //po konwersji true
//wiec
true==($a==0) // false
true==($a<0) // false
true==($a>0) // true

$a=0; //po konwersji false
//wiec
false==($a==0) // false poniewaz ($a==0) daje true
false==($a<0) // true i tutaj jest zatrzymywane sprawdzanie bo warunek prawdziwy i reszta jest pomijana
false==($a>0) // ...
blooregard
No teraz wszystko jasne.
Dzięki.
ucho
  1. <?php
  2. switch (true) {
  3.   case ($a ==0): echo ' = 0'; break;
  4.   case ($a < 0): echo ' < 0'; break;
  5.   case ($a > 0): echo ' > 0'; break;
  6. }
  7. ?>

  1. <?php
  2. function sgn($int) {
  3.    if($int > 0) return 1;
  4.    if($int < 0) return -1;
  5.    return 0;
  6. }
  7. switch (sgn($a)) {
  8.   case (0): echo ' = 0'; break;
  9.   case (-1): echo ' < 0'; break;
  10.   case (1): echo ' > 0'; break;
  11. }
  12. ?>

Albo jedno, albo drugie, mieszanie jak widać nie jest zalecane smile.gif Swoją drogą cytat z http://bugs.php.net/bug.php?id=35025&edit=1:
Cytat
No need for yet another one rarely used core function.

To brzmi jak przeciwieństwo zasad którymi kierowali się twórcy PHP tongue.gif
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.