За последние 24 часа нас посетили 17528 программистов и 1283 робота. Сейчас ищут 1380 программистов ...

Башоргру ЖГЁТ - или сборник лучшего

Тема в разделе "HUMOR.PHP.RU", создана пользователем Psih, 21 мар 2007.

  1. AlexGousev

    AlexGousev Активный пользователь

    С нами с:
    25 мар 2006
    Сообщения:
    1.505
    Симпатии:
    0
    Адрес:
    Москва
    Вот вам не спится: задача века :)
     
  2. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    отключи оптимизации и увидишь, что он говорит одно и то же.
    Dagdamor, в том-то и дело, что в некоторых языках этот код равнозначен такому:
    Код (Text):
    1. int i; i= (i=i+1)+(i=i+1);
    , то биш он просто имеет более высокий приоритет при выполнении. в других же происходит честный вынос инкремента за пределы выражения
    Код (Text):
    1. int i; ++i; ++i; i=i+i
    .
     
  3. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    dark-demon
    Не понимаю я твоей логики в упор :) Почему, если компилятор вносит в твое выражение отсебятину (меняет операции местами), это называется "честным выносом инкремента"?
    Пока что я понял одно: не стоит использовать подобные выражения, если ты хочешь, чтобы твоя программа работала независимо от реализации компилятора. :D

    Amian
    Это я понял, что вместо вычисления "++i + ++i" он по сути вычисляет "++i; ++i; +". Я не понял, почему второе считается эквивалентным первому...

    Я бы попросил ;)
     
  4. AlexGousev

    AlexGousev Активный пользователь

    С нами с:
    25 мар 2006
    Сообщения:
    1.505
    Симпатии:
    0
    Адрес:
    Москва
    Логика простая: работать в соответствии с заранее четко определенным списком приоритетов операций.
    Операции должны выполняться по порядку, начиная с самой важной. Для изменения порядка операций есть такая штука как скобки.
    Приоритет операций для того и придумали, чтобы неоднозначностей не возникало. А то, что делает PHP - баг.
     
  5. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    AlexGousev
    Ну хорошо, давай отталкиваться от приоритета. Выражение такое:
    (++i) + (++i)

    1. Выполняется операция в первой скобке. Т.к. она является частью выражения, она возвращает результат (6). i = 6.
    2. Выполняется операция во второй скобке. Ее результат - 7 (i равно 7).
    3. Полученные результаты складываются, результат всего выражения 13.
    Верно?
     
  6. AlexGousev

    AlexGousev Активный пользователь

    С нами с:
    25 мар 2006
    Сообщения:
    1.505
    Симпатии:
    0
    Адрес:
    Москва
    Неа:
    1. Выполняется инкремент переменной i
    2. Выполняется инкремент переменной i
    3. Присваивается значение переменной i первой скобке
    4. Присваивается значение переменной i второй скобке
    5. Складываются значения первой и второй скобок

    Хитрость в том, что операция ++i имеет больший приоритет, чем операция присвоения значения, а операция i++ меньший и в этом разница
     
  7. AlexGousev

    AlexGousev Активный пользователь

    С нами с:
    25 мар 2006
    Сообщения:
    1.505
    Симпатии:
    0
    Адрес:
    Москва
    Полез в документацию посмотреть…
    В PHP и C операции инкремента разные по сути.
    В С:
    Прибавляет единицу к переменной либо до, либо после вычисления всего выражения.
    В PHP:
    ++i прибавляет к переменной единицу в момент вычисления текущего куска выражения и возвращает значение.
    i++, соответственно, сначала возвращает значение, потом прибавляет единицу.
     
  8. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    поведение РНР мне кажется более "приятным", обидно что в Си не так...
     
  9. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    да. в си префиксный инкремент увеличивает значение переменной без копирования значения. это значит, что при вычислении выражения переменная будет равна 7 во всех местах.
     
  10. Вльдемар

    Вльдемар Активный пользователь

    С нами с:
    20 май 2006
    Сообщения:
    635
    Симпатии:
    0
    Адрес:
    Белхород
    PHP:
    1. <?
    2. $i=5;
    3. $i=++$i + ++$i;
    4. echo $i;
    5. ?>
    ответ 13
     
  11. AlexGousev

    AlexGousev Активный пользователь

    С нами с:
    25 мар 2006
    Сообщения:
    1.505
    Симпатии:
    0
    Адрес:
    Москва
    Вльдемар
    Это мы выяснили на предыдущей странице. С этого все и началось…

    Ты где нибудь в одном выражении два префиксных инкремента когда-нибудь использовал? Я просто не представляю где это можно использовать.


    Ну и возвращаясь к теме топика:
     
  12. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    В математических вычислениях (ряд Тейлора и.т.д.) использую часто...
    (иногда не получалось "портировать" с РНР на Си с первого раза, видимо это и была причина)
     
  13. Петр

    Петр Активный пользователь

    С нами с:
    20 мар 2006
    Сообщения:
    1.253
    Симпатии:
    0
    Адрес:
    Центр Вселенной
    Да, ребята....
    Мы раскрыли заговор века =)
    Мне, пожалста, парочку светлого будущего =)
     
  14. Ti

    Ti Активный пользователь

    С нами с:
    3 июл 2006
    Сообщения:
    2.378
    Симпатии:
    1
    Адрес:
    d1.ru, Екатеринбург
     
  15. Amian

    Amian Активный пользователь

    С нами с:
    15 мар 2007
    Сообщения:
    189
    Симпатии:
    0
    Логика у компа не в "выражениях",а такая:
    0 - иницилизируем переменную "int i",под неё выделяется память с адресом 0xFFFF, например.
    1- транслятор C расставляет инструкции ассемблера согласно приорететам(inc si,inc si ... mov si ax)
    2- выполняется первая операция,происходит обращение к памяти по адресу 0xFFFF,число увеличивается на 1 по этому адресу.
    3 - выполняется вторая операция,происходит обращение к памяти по адресу 0xFFFF,число увеличивается на 1 по этому адресу.
    4 - выполняется третья операция - сложения 1-го числа с другим и записывается результат.Обрашаемся к левой стороне - адрес 0xFFFF value 0...0111(7 dec),обращаемся к правой стороне - 0xFFFF value 0...0111(7 dec),складываем (7+7=14).
    5 - записываем результат в ячейку с адресом 0xFFFF.

    В PHP происходит абсолютно тоже самое,только в нём есть баг - во время трансляции он скорее всего интерпретирует ++i операцию как i=i+1,не используя инструкцию ассемблера "inc",поэтому и приорететы меняются.И происходит что-нибудь типа:

    Код (Text):
    1.      
    2.         //инкремент на 1
    3.         mov     ax,si
    4.         add     ax,1
    5.         mov     si,ax
    6.         //сложение  
    7.         mov     ax,si        
    8.         add     ax,si
    9.         mov     si,ax
    10.         //инкремент на 1
    11.         mov     ax,si
    12.         add     ax,1
    13.         mov     si,ax
    Результат тогда будет:
    1)5+1=6
    2)6+6=12
    3)12+1=13
    Извеняюсь если ляпнул чего лишнего,никого не хотел обидеть :)
     
  16. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    тот же самый баг мы наблюдаем и в JS и в C# и ещё небось в половине других языков :)
     
  17. Петр

    Петр Активный пользователь

    С нами с:
    20 мар 2006
    Сообщения:
    1.253
    Симпатии:
    0
    Адрес:
    Центр Вселенной
    dark-demon, самое интересное, что в C++ CLI, в отличие от C#, мы этого не наблюдаем,
    хотя и то и другое транслируется в MSIL.
     
  18. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    Петр, очевидно потому, что это всё-таки C++ :) пусть и компилируемый в байткод не реальной, а виртуальной машины...
     
  19. AlexGousev

    AlexGousev Активный пользователь

    С нами с:
    25 мар 2006
    Сообщения:
    1.505
    Симпатии:
    0
    Адрес:
    Москва
    Amian
    Почитайте топик целиком — уже во всем разобрались… что баг не баг, а фича :)
     
  20. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    AlexGousev
    :D
     
  21. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    Достойно башорга
     
  22. dark-demon

    dark-demon Активный пользователь

    С нами с:
    16 фев 2007
    Сообщения:
    1.920
    Симпатии:
    1
    Адрес:
    леноград
    Он: да уж не любовь - точно :)
     
  23. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
     
  24. AlexGousev

    AlexGousev Активный пользователь

    С нами с:
    25 мар 2006
    Сообщения:
    1.505
    Симпатии:
    0
    Адрес:
    Москва
    Psih
    Мне за сегодня больше всего понравилось
     
  25. Psih

    Psih Активный пользователь
    Команда форума Модератор

    С нами с:
    28 дек 2006
    Сообщения:
    2.678
    Симпатии:
    6
    Адрес:
    Рига, Латвия
    А мне понравились ещё вот эти два: