Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Что будет выведено в результате следующего кода? echo true ? false ? 5 : 6 : true ? 7 : 8 
:(
    Опции темы
ruskar
Дата 10.3.2009, 08:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 18.1.2009

Репутация: нет
Всего: нет



Попался мне тут один тестик. На первый взгляд весьма простой. Логически просчитав его в уме, я получил одно значение. Запускаю для проверки код, и… интерпретатор PHP выдаёт мне совсем другое. Задачка была следующая:

Код

$c = ($a == $b || $a <= 2) ? ($a == 2) ? 1 : 2 : ($b > $a && $a > 2) ? ($b > 2) ? 3 : 4 : ($a < 5 || $b < 2) ? ($b == 4) ? 5 : 6 : (1 == 1) ? 7 : 8;


Отмечаю, что переменные $a и $b не инициализированы, соответственно в данном выражении они везде примут значение false. Тернарный оператор ?: имеет правую ассоциативность, но выражение выполняется как-то вообще ни правым, ни левым способом. Для понимания ситуации возьму кусок правой части выражения, в котором уже видна проблема, и упрощу его:

Код

echo true ? false ? 5 : 6 : true ? 7 : 8;


Если я правильно понимаю ассоциативность, то порядок выполнения операций здесь такой:

1. Сначала выполняется true ? 7 : 8, в результате получаем 7.
2. Затем выполняется false ? 5 : 6, в результате получаем 6.
3. В конце выполняется true ? 6 : 7, в результате получаем… думаете 6? А вот и нет, выводится 7!

Так каков же на самом деле порядок выполнения операций? И почему мы получаем в результате 6?

Это сообщение отредактировал(а) ruskar - 10.3.2009, 08:26
PM MAIL   Вверх
ksnk
Дата 10.3.2009, 08:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


прохожий
****


Профиль
Группа: Комодератор
Сообщений: 6855
Регистрация: 13.4.2007
Где: СПб

Репутация: 96
Всего: 386



Если скобочки расставить так, как сделал бы это PHP - получится вот так:
Код

echo (true ? (false ? 5 : 6) : true) ? 7 : 8;





--------------------
Человеку свойственно ошибаться, программисту свойственно ошибаться профессионально ! user posted image
PM MAIL WWW Skype   Вверх
MoLeX
Дата 10.3.2009, 08:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Местный пингвин
****


Профиль
Группа: Модератор
Сообщений: 4076
Регистрация: 17.5.2007

Репутация: 46
Всего: 140



ruskar, совет - приведи в обычный вид.


--------------------
Amazing  smile 
PM MAIL WWW ICQ   Вверх
ruskar
Дата 10.3.2009, 08:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 18.1.2009

Репутация: нет
Всего: нет



Цитата(ksnk @ 10.3.2009,  08:50)
Если скобочки расставить так, как сделал бы это PHP - получится вот так:
Код

echo (true ? (false ? 5 : 6) : true) ? 7 : 8;

Разве? То, что вы показываете, называется _левой_ ассоциативностью, а тернарный оператор имеет _правую_ ассоциативность. 

Вообщем кажется я понял как это решается. Сначала выполняется:

Код

true ? 7 : 8


в результате возвращается 7 и дальнейшее выражение выглядит примерно так:

Код

echo true ? false ? 5 : 6 : 7;


Затем уже выполняется: 

Код

false ? 5 : 6 : 7;


И тут казалось бы интерпретатор видимо берёт «самое правое» значение 7, после чего всё становится логичным, НО…

Код

echo false ? 5 : 6 : 7;


Выдаёт 6! Всё, я окончательно запутался о_О

Добавлено @ 09:05
Цитата(MoLeX @ 10.3.2009,  08:51)
ruskar, совет - приведи в обычный вид.

Это как?

Тут ещё возникла версия, что интерпретатор просто берёт самое правое вхождение тернарного оператора, а всё остальное отметает. Т.е. выражение вида:

Код

echo true ? false ? 5 : 6 : true ? 7 : 8;


превращается в:

Код

echo true ? 7 : 8;


Тогда с результатами экспериментов всё сходится. Хотя что-то я с подозрением отношусь к этой версии.

Это сообщение отредактировал(а) ruskar - 10.3.2009, 09:07
PM MAIL   Вверх
Akina
Дата 10.3.2009, 09:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Советчик
****


Профиль
Группа: Модератор
Сообщений: 20581
Регистрация: 8.4.2004
Где: Зеленоград

Репутация: 5
Всего: 454



Цитата(ruskar @  10.3.2009,  09:59 Найти цитируемый пост)
То, что вы показываете, называется _левой_ ассоциативностью, а тернарный оператор имеет _правую_ ассоциативность.

А не поленитесь сперва посмотреть справку, а? тогда не придётся выдавать вот такого рода фразы...


--------------------
 О(б)суждение моих действий - в соответствующей теме, пожалуйста. Или в РМ. И высшая инстанция - Администрация форума.

PM MAIL WWW ICQ Jabber   Вверх
ruskar
Дата 10.3.2009, 09:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 18.1.2009

Репутация: нет
Всего: нет



Пардон, меня дезинформировали насчёт:

Код

echo false ? 5 : 6 : 7;


оказывается здесь в результате вообще выдаётся ошибка: 

Код

Parse error: parse error, expecting `','' or `';'' in C:\Apache\htdocs\localhost\index.php on line 15


Это сообщение отредактировал(а) ruskar - 10.3.2009, 09:12
PM MAIL   Вверх
ruskar
Дата 10.3.2009, 10:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 8
Регистрация: 18.1.2009

Репутация: нет
Всего: нет



Извиняюсь, Akina оказался прав. Просто я когда начал проверять результаты своего вычисления в голове, полез за объяснением во всемогущий Гугл, чтобы узнать ассоциативность тернарного оператора (точнее, чтобы убедиться, что он имеет правую ассоциативность). Половина найденных в онлайне учебников говорила, что да, тернарный оператор имеет правую ассоциативность (например тут: http://depositfiles.od.ua/php/03.php), поэтому я и попал в ступор. Потом уже когда перерыл официальную документацию, всё же нашёл, что тернарный оператор в PHP имеет левую ассоциативность, и на самом деле это является ошибкой. Нашёл у тёти Вики страничку с подробным описанием проблемы. Цитата:

Цитата

Код

$arg = "T";
$vehicle = ( ( $arg == 'B' ) ? 'bus' : 
             ( $arg == 'A' ) ? 'airplane' : 
        ( $arg == 'T' ) ? 'train' : 
        ( $arg == 'C' ) ? 'car' : 
        ( $arg == 'H' ) ? 'horse' : 
               'feet' );
echo $vehicle;


Due to an unfortunate error in the language grammar, the implementation of ?: in PHP uses the incorrect associativity when compared to other languages, and given a value of T for arg, the PHP equivalent of the above example would yield the value horse instead of train as one would expect.


Добавлено через 9 минут и 47 секунд
Akina, а если брать исходное тестовое задание, и делать по левой ассоциативности, то где я допускаю ошибку? Вот смотри, если исходное тестовое сократить, вычислив выражения в скобках, то получится:

Код

echo true ? false ? 1 : 2 : false ? false ? 3 : 4 : true ? false ? 5 : 6 : true ? 7 : 8;


Выводит 7. Исходя теперь уже из левой ассоциативности расставляем скобки:

Код

echo ((true ? (false ? 1 : 2) : false) ? (false ? 3 : 4) : true) ? (false ? 5 : 6) : (true ? 7 : 8);


Выводит 6. о_О Не пойму, почему. Как же всё-таки интерпретатор РНР считает это выражение? Хочется всё-таи докопатся до сути.
PM MAIL   Вверх
sTa1kEr
Дата 11.3.2009, 12:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


9/10 программиста
***


Профиль
Группа: Завсегдатай
Сообщений: 1553
Регистрация: 21.2.2007

Репутация: 56
Всего: 146



Цитата(ruskar @  10.3.2009,  11:12 Найти цитируемый пост)
Выводит 6. о_О Не пойму, почему.

Кто-же так скобки-то расставляет? Слева-направо означает слева-направо, а не наобум.

1. echo true ? (false ? 1 : 2) : false ? false ? 3 : 4 : true ? false ? 5 : 6 : true ? 7 : 8;
2. echo (true ? (false ? 1 : 2) : false) ? false ? 3 : 4 : true ? false ? 5 : 6 : true ? 7 : 8;
3. echo (true ? (false ? 1 : 2) : false) ? (false ? 3 : 4) : true ? false ? 5 : 6 : true ? 7 : 8;
4. echo ((true ? (false ? 1 : 2) : false) ? (false ? 3 : 4) : true) ? false ? 5 : 6 : true ? 7 : 8;
5. echo ((true ? (false ? 1 : 2) : false) ? (false ? 3 : 4) : true) ? (false ? 5 : 6) : true ? 7 : 8;
6. echo (((true ? (false ? 1 : 2) : false) ? (false ? 3 : 4) : true) ? (false ? 5 : 6) : true) ? 7 : 8;
7. echo ((((true ? (false ? 1 : 2) : false) ? (false ? 3 : 4) : true) ? (false ? 5 : 6) : true) ? 7 : 8);

PM MAIL   Вверх
nerezus
Дата 11.3.2009, 13:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Вселенский отказник
****


Профиль
Группа: Участник
Сообщений: 3330
Регистрация: 15.6.2005

Репутация: 12
Всего: 43



Цитата

Что будет выведено в результате следующего кода? echo true ? false ? 5 : 6 : true ? 7 : 8
 Увольнение этого писаря.


--------------------
Сообщество художников Artsociety.ru
PM MAIL WWW   Вверх
skyboy
Дата 11.3.2009, 16:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


неОпытный
****


Профиль
Группа: Модератор
Сообщений: 9820
Регистрация: 18.5.2006
Где: Днепропетровск

Репутация: 75
Всего: 260



Цитата(nerezus @  11.3.2009,  12:36 Найти цитируемый пост)
Увольнение этого писаря.

не напрягайся. это не реальный код
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "PHP"
Aliance
IZ@TOP
skyboy
SamDark
MoLeX

Новичкам:

  • PHP редакторы собираются и обсуждаются здесь
  • Электронные книги по PHP, документацию можно найти здесь
  • Интерпретатор PHP, полную документацию можно скачать на PHP.NET

Важно:

  • Не брезгуйте пользоваться тегами [code=php]КОД[/code] для повышения читабельности текста/кода.
  • Перед созданием новой темы воспользуйтесь поиском и загляните в FAQ
  • Действия модераторов можно обсудить здесь

Внимание:

  • Темы "ищу скрипт", "подскажите скрипт" и т.п. будут переноситься в форум "Web-технологии"
  • Темы с именами: "Срочно", "помогите", "не знаю как делать" будут УДАЛЯТЬСЯ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, IZ@TOP, skyboy, SamDark, MoLeX, awers.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0672 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.