Linux за българи: Форуми

Програмиране => Конкурс bash-майсторът => Темата е започната от: VladSun в Mar 17, 2010, 14:14



Титла: [PHP] Условности 2
Публикувано от: VladSun в Mar 17, 2010, 14:14
Тъй като е свързано с темата, мисля да ви "погъделичкам" още малко ...

Задачка: Без да изпълнявате скрипта в PHP, какъв мислите ще е изходът от този скрипт:

Код
GeSHi (PHP):
  1. function foo($v)
  2. {
  3.    echo $v ? 'true ' : 'false ';
  4.    return !$v;
  5. }
  6.  
  7. function bar($v)
  8. {
  9.    echo !$v ? 'true ' : 'false ';
  10.    return $v;
  11. }
  12.  
  13. $v = true;
  14. echo ($v = foo($v) or bar($v)) ?  'true ' : 'false ';

 >:D >:D >:D


Титла: Re: [PHP] Условности 2
Публикувано от: VladSun в Mar 17, 2010, 14:36
false
false
false

Нещо омазах разделянето на темата :(


Титла: Re: [PHP] Условности 2
Публикувано от: VladSun в Mar 17, 2010, 14:38
Ще изчакам и другите да дадат отговори ;)


Титла: Re: [PHP] Условности 2
Публикувано от: gat3way в Mar 17, 2010, 15:04
true
(не съм убеден, вероятно false)
false



Титла: Re: [PHP] Условности 2
Публикувано от: neter в Mar 17, 2010, 16:01
Хехе, тъй като съвсем наскоро в миналата тема за условностите си играх със задаване на стойности на променливи в структурата на други елементи, нямаше как да се излъжа:
Цитат
true
true
false
Обяснявам защо. Редът
Код
GeSHi (PHP):
  1. $v = foo($v)
не е проверка на стойност, а е задаване на променлива (обърнете внимание на броя на знаците "=" - имаме само 1, а не 2 или 3), и въпреки това, че се намира в структурата на if, задаването на променливата се изпълнява. Така че, при изпълнението на реда
Код
GeSHi (PHP):
  1. echo ($v = foo($v) or bar($v)) ?  'true ' : 'false ';
първо имаме задаване на променливата $v да бъде равна на резултата от функцията foo($v). При изпълнението на тази функция, на екрана се принтира "true", тъй като текущо $v е true, а функцията връща стойност false (обратното на стойността на $v), което застава като стойност на $v. Т.е., оттук нататък $v е false. При изпълнението на bar($v) имаме принтиране на "true", тъй като $v текущо е false. Така, в крайна сметка в if-а остава "false or false", което изкарва на екрана "false". Много интересно ми стана напоследък задаването на стойности на променливи на нестандартни места [_]3


Титла: Re: [PHP] Условности 2
Публикувано от: gat3way в Mar 17, 2010, 16:09
Не е толкова логично първо да е "равно", после да е "или". Замени "or" с "||" и ще се изненадаш от резултата :)

Обаче тази дребна особеност съм я срещал преди :)


Титла: Re: [PHP] Условности 2
Публикувано от: neter в Mar 17, 2010, 18:01
Това вече е интересно. Значи "or" не е пълен alias на "||". Стигнах до тези заключения. Когато се използва "or", стойността на променливата се задава веднага, и участва в следващите проверки на if-a. Но когато се използва "||", стойността на променливата започва да действа след приключването на if-а. И още нещо. Когато се използва "or", стойността на променливата се приема такава, каквато се задава (числова, булева...), но когато се използва "||", стойността на променливата се приема булева (ако зададеш "5", променливата става равна на "true", а не на "5"). В крайна сметка, при задаването на променливата и в двата случая в if-а остава булева стойност, на мястото на задаването на променливата, но при различните случаи имаме различна стойност на променливата и различен момент на нейното реално задаване. Цялата тази схема важи и за "&&" и неговия alias "and". Много интересно :)


Титла: Re: [PHP] Условности 2
Публикувано от: gat3way в Mar 17, 2010, 18:31
Да, аз съм се чудил защо по дяволите в PHP има два еквивалентни набора логически оператора. В C примерно няма такива неща. Не че някои неща в PHP не ми изглеждат безкрайно странни, обаче това ми се видя абсолютно безсмислено. После се оказа че имало все пак разлика в приоритетите им :)

Иначе за вторият true/false имах съмнения в това дали "!" има приоритет пред съкратените if глупости и понеже видях, че нещата се въртят около тези проблеми, реших че Vladsun е заложил някакъв капан и там :) ама не съм познал.

Някъде дали няма нещо като таблица кое с по-голям приоритет в PHP?


Титла: Re: [PHP] Условности 2
Публикувано от: pikimos в Mar 17, 2010, 18:43
Дайте нещо и за C++ :)


Титла: Re: [PHP] Условности 2
Публикувано от: VladSun в Mar 17, 2010, 19:05
Всичко произтича от два факта:

1) or/and операторите са с по-нисък приоритет от оператора за присвояване "=";
2)  >:D българската версия на PHP ръководството пропуска "минорни" забележки - сравнете http://www.php.net/manual/bg/language.operators.logical.php и http://bg.php.net/manual/en/language.operators.logical.php

Иначе в таблицата за приоритетите е ясно: http://www.php.net/manual/en/language.operators.precedence.php

Т.е. нашата задачка се развива във:

Код
GeSHi (PHP):
  1. $v =
  2. (
  3.  (
  4.     $v = foo($v)
  5.   )
  6.   or
  7.   bar($v)
  8. )



Титла: Re: [PHP] Условности 2
Публикувано от: neter в Mar 17, 2010, 20:27
Добре, ясно защо моментът на задаване на променливата е различен при различните двойки оператори - следваме списъка на приоритетите. Но нещо не можах да си отговоря защо при различните двойки оператори имаме различна крайна стойност на променливата? В тази задача така или иначе задаваме булева стойност на променливата и не си личи, но ако зададем числова (например "5"), защо при "and/or" имаме $v=5, а при "&&/||" имаме $v=true? Аналогично, ако зададем $v=0, то при "and/or" имаме $v=0, а при "&&/||" получаваме $v=false ???


Титла: Re: [PHP] Условности 2
Публикувано от: VladSun в Mar 17, 2010, 23:30
@neter

Имаш предвид защо:
Код
GeSHi (PHP):
  1. $v = 5 or 4;
  2.  
  3. $v = 5 || 4;
  4.  
ще изкара :
Код:
int 5
boolean true
ли?

Пак заради приоритетите - при едното имаме
($v=5) or 4    => $v === 5

при второто имаме
$temp = (5 || 4), операторът || връща *винаги* булева стойност => $temp === true => $v = true

Най-лесно е да видиш изхода от:
Код
GeSHi (PHP):
  1. $v = (5 or 4);
=>
Код:
boolean true

Освен това, изразът "4" в първия пример изобщо не се взима под внимание заради short-circuit evaluation-а


Титла: Re: [PHP] Условности 2
Публикувано от: neter в Mar 18, 2010, 00:47
Да, сега вече ми стана ясно. Аз гледах на приоритетите като отделни точки на изпълнение, въобще не се сетих да ги погледна като части на "изречение" :) Много благодаря за разяснението, отвори ми се играчка на тема приоритети [_]3


Титла: Re: [PHP] Условности 2
Публикувано от: VladSun в Mar 18, 2010, 13:18
Да, аз съм се чудил защо по дяволите в PHP има два еквивалентни набора логически оператора. В C примерно няма такива неща. Не че някои неща в PHP не ми изглеждат безкрайно странни, обаче това ми се видя абсолютно безсмислено. После се оказа че имало все пак разлика в приоритетите им :)

Въпреки (и заради) разликата в приоритетите, за мене е абсолютна глупост съществуването на OR/AND операторите :)


Титла: Re: [PHP] Условности 2
Публикувано от: neter в Mar 18, 2010, 13:56
Въпреки (и заради) разликата в приоритетите, за мене е абсолютна глупост съществуването на OR/AND операторите :)
Защо? Дава се свобода на програмиста. Досега не ми се е налагало да се възползвам от тази свобода, но никак не е изключено някой път да ми се наложи, и, ако я няма тази свобода, ще трябва да загрозявам кода, вместо просто да заменя оператора (сигурно може да се измисли и по-солидно тюхкане, но не ми се мисли за такова сега). Гледам, че тази свобода я има и в javascript. Ако човек не иска да рискува да обърка нещо в логиката на кода, в резултат на едновременното използване на двете двойки оператори, може просто винаги да ползва едната двойка, и да е спокоен - това, че втората двойка съществува, не го обвързва по никакъв начин. Пък нека я има свободата за тези, на които тази свобода ще е от полза. Ако тази свобода по някакъв начин задължи тези, които не я използват, да указват допълнителни неща, заради съществуването й, и да се обвързват по някакъв начин, тогава и аз бих се възпротивил.


Титла: Re: [PHP] Условности 2
Публикувано от: gat3way в Mar 18, 2010, 14:04
Няма нужда - те скобите за това са направени.


Титла: Re: [PHP] Условности 2
Публикувано от: VladSun в Mar 18, 2010, 14:10
Не мога да се съглася...

По същата логика трябва да има и BAND/BOR (bitwise AND/OR), които да са с по-нисък приоритет от оператора за присвояване ... или можем да добавим огледално приоритетите по отношение на оператора "," ...

Е! До къде ще го докараме така ?!? :)

Тази тема показа (а и това беше целта), че съществуването на AND/OR операторите в PHP, в този си вид е объркващо и източник на грешки.

Има си оператор за тия неща - скобите :)

ПП: gat3way ме изпревари:)