киберпанк и задачка) - ответ)

Discussion in 'Болталка' started by sn0w, 15 Jul 2011.

  1. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,023
    Likes Received:
    1,309
    Reputations:
    327
    [​IMG]

    на самом деле меня тоже сперва смутило) правда я не любитель писать стихи посредством кода, поскольку зачастую чревато багами и в общем - хреновой читабельностью, однако и тут есть некоторый кураж)

    фишка в том что компилеры визуала и билдера генерят код примерно такой:

    Code:
    i=5;
    i++;
    i++;
    i+=i;
    
    что вполне справедливо для компилятора использующего одну ячейку памяти (под i конечно) и
    в чем впрочем можно убедиться взяв асм листинг.

    Code:
    .text:00401000                 push    ebp
    .text:00401001                 mov     ebp, esp
    .text:00401003                 push    ecx
    .text:00401004                 mov     [ebp+i], 5      ; i=5
    .text:0040100B                 mov     eax, [ebp+i]
    .text:0040100E                 add     eax, 1
    .text:00401011                 mov     [ebp+i], eax    ; i++; i==6
    .text:00401014                 mov     ecx, [ebp+i]
    .text:00401017                 add     ecx, 1
    .text:0040101A                 mov     [ebp+i], ecx    ; i++; i==7
    .text:0040101D                 mov     edx, [ebp+i]
    .text:00401020                 add     edx, [ebp+i]
    .text:00401023                 mov     [ebp+i], edx    ; i += i; i==7+7==14
    .text:00401026                 mov     eax, [ebp+i]
    .text:00401029                 push    eax
    .text:0040102A                 push    offset Format   ; "%d"
    .text:0040102F                 call    ds:__imp__printf
     
    #1 sn0w, 15 Jul 2011
    Last edited: 15 Jul 2011
  2. M_script

    M_script Members of Antichat

    Joined:
    4 Nov 2004
    Messages:
    2,581
    Likes Received:
    1,317
    Reputations:
    1,557
    Меня наоборот левая часть смутила. Очевидно же, что 14 должно быть.
     
  3. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,023
    Likes Received:
    1,309
    Reputations:
    327
    а я сперва посчитал 13)) видать отвык)
    но слева то другой вопрос. приоритеты операций везде одинаковые, но ++i виртуалка сохраняет как одно значение, а еще ++i - как еще одно. и они то и складываются.
     
  4. ShyRka_coder

    ShyRka_coder Member

    Joined:
    27 Jul 2010
    Messages:
    127
    Likes Received:
    7
    Reputations:
    5
    интересна:) сяб
     
  5. Ins3t

    Ins3t Харьковчанин

    Joined:
    18 Jul 2009
    Messages:
    939
    Likes Received:
    429
    Reputations:
    139
    нe очeвидно. стaндaрт в тaких случaях ничeго нe гaрaнтируeт и рaзныe компили будут гeнeрить рaзный код.
     
  6. <Cyber-punk>

    <Cyber-punk> Smash the Stack

    Joined:
    1 Oct 2009
    Messages:
    658
    Likes Received:
    315
    Reputations:
    430
    Интересные факты) и всё из-за одной картинки))
     
    _________________________
  7. X-rus

    X-rus Member

    Joined:
    22 Dec 2010
    Messages:
    88
    Likes Received:
    22
    Reputations:
    4
    Есть такая тема - порядок операторов. Нашёл ссылки с порядком операторов.

    C#
    C++

    У C++ и C# они отличаются. У C++ префиксный ++ выше +, а в C# они на одном уровне. Вот и разгадка. :)


    Нет, ошибся и окончательно запутался. :)
     
    #7 X-rus, 15 Jul 2011
    Last edited: 15 Jul 2011
  8. Ins3t

    Ins3t Харьковчанин

    Joined:
    18 Jul 2009
    Messages:
    939
    Likes Received:
    429
    Reputations:
    139
    кому интересно, на васме весьма живо обсуждали эту тему.
    http://wasm.ru/forum/viewtopic.php?id=20504&p=1
     
  9. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,023
    Likes Received:
    1,309
    Reputations:
    327
    да вот не соглашусь, иначе какой код компилеру генерить
    if(random()) // +
    else // ++

    :D

    на самом деле префиксный инкремент и в сях и в шарпе имеет приоритет выше чем аддитивные операторы.
     
  10. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,023
    Likes Received:
    1,309
    Reputations:
    327
    да не, по сути все верно - вопрос в памяти. если добавить вторую переменную, например, то мы и получим 13, аля как это срабатывает в манагед-коде.

    proof of concept:

    int y, i = 5;
    y = ++i;
    i = y + ++i;

    printf("%d", i);
    результат == 13

    просто за счет того что i не переписывается дважды.
     
  11. Lee_fx

    Lee_fx Elder - Старейшина

    Joined:
    27 Sep 2008
    Messages:
    90
    Likes Received:
    14
    Reputations:
    0
    В пределах двух точек следования переменная не должна меняться более одного раза, иначе неопределенное поведение гарантировано) Это я о С++

    i = ++i + ++i;
    тут i меняется три раза, вместо положенного одного
     
  12. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,023
    Likes Received:
    1,309
    Reputations:
    327
    i является стековой переменной. в листинге под нее место выделяется за счет push ebx, далее [ebp-4] является указателем на нее. разбирая выражение i = ++i + ++i в хронологическом порядке, получаем что выполняем первый инкремент, [ebp-4] увеличивается на единицу. второй инкремент - опять тоже самое происходит. ну и наконец суммируем результат - тк хранится она у нас в одном месте, то и получаем вполне обоснованный результат)
     
  13. M_script

    M_script Members of Antichat

    Joined:
    4 Nov 2004
    Messages:
    2,581
    Likes Received:
    1,317
    Reputations:
    1,557
    Конкретно для этого примера можешь назвать компилятор C++ , в которым не 14 будет?
     
  14. Ins3t

    Ins3t Харьковчанин

    Joined:
    18 Jul 2009
    Messages:
    939
    Likes Received:
    429
    Reputations:
    139
    проверил на всех компилях, что у меня есть. везде 14. но это не значит, что результат определен. может быть и другой результат, нужно только хорошенечко потестить на всем, чем только можно ;)
     
  15. Nelz.

    Nelz. Member

    Joined:
    2 Aug 2010
    Messages:
    151
    Likes Received:
    7
    Reputations:
    0
    так давайте начиная с паскаля заканчивая от js

    PHP:
    <?php

    $i 
    5
    $i =  ++$i + ++$i;

    echo 
    $i;

    ?>
    13
     
  16. M_script

    M_script Members of Antichat

    Joined:
    4 Nov 2004
    Messages:
    2,581
    Likes Received:
    1,317
    Reputations:
    1,557
    Еще из той же серии:
    i = 5; i = i+++i;
    11 или 12?
     
  17. Nelz.

    Nelz. Member

    Joined:
    2 Aug 2010
    Messages:
    151
    Likes Received:
    7
    Reputations:
    0
    11 пыхпых
     
    #17 Nelz., 15 Jul 2011
    Last edited: 15 Jul 2011
  18. Ins3t

    Ins3t Харьковчанин

    Joined:
    18 Jul 2009
    Messages:
    939
    Likes Received:
    429
    Reputations:
    139
    мы о с++ говорили вообще то.
     
  19. Nelz.

    Nelz. Member

    Joined:
    2 Aug 2010
    Messages:
    151
    Likes Received:
    7
    Reputations:
    0
    я знаю,дело в том,почему у всех разные ?
     
  20. sn0w

    sn0w Статус пользователя:

    Joined:
    26 Jul 2005
    Messages:
    1,023
    Likes Received:
    1,309
    Reputations:
    327
    думаю 12, ща проверю

    ооо вот это уже ништяк)))))))))))

    при конфиге прожекта Release если отключить все оптимизации компилятора получаем 12, если выбрать быстрый код - 11

    (VS2010)
     
    #20 sn0w, 15 Jul 2011
    Last edited: 15 Jul 2011