argon bulletin board

Експертно търсене  

Новини:

Регистрирането на нови потребители е временно деактивирано.

Автор Тема: Една задачка - закачка!  (Прочетена 1822 пъти)

Jack Johnson

  • Неактивен Неактивен
  • Публикации: 704
  • Хора, пазете си здравето! То няма цена!
Една задачка - закачка!
« -: 17.01.2011, 18:22:04 »

Ако "а = 3", тогава каква е стойността на "a" след изпълнението на следния израз:

a += a++ + ++a
Това е малко в стил "вижте колко шантав код може да измисли човек", но е добро упражнение за мозъка. Който иска да види крайния отговор без да си размърда мозъчните клетки, copy/paste на долния ред в URL полето на браузъра и Enter.

javascript:{var a = 3; a += (a++ + ++a); alert(a);}
P.S. Ами ако "а = 4"?
« Последна редакция: 17.01.2011, 18:24:02 от Иван Давидов »
Активен

xyz--

  • Гост
Re:Една задачка - закачка!
« Отговор #1 -: 17.01.2011, 20:24:19 »

Интересен код.
4 += (4 + 6), което е равно на 14 е отговорът, показан от browser-а.
Като го компилирам с gcc, става друго.
a += (4 + 6), понеже след ++ a=6, крайното е 16.
Може би реализациите са различни.
Активен

lamerko

  • Неактивен Неактивен
  • Публикации: 211
    • Моят блог
Re:Една задачка - закачка!
« Отговор #2 -: 17.01.2011, 20:26:34 »

11; 14;

Или:

3 += (3++ + 4) = 3 += 8 = 11;
4 += (4++ + 5) = 4 += 10 = 14;

И какъв е смисъла да слагаш решението :)

ed:

xyz++: всичко опира до интерпретация на ++х и х++
« Последна редакция: 17.01.2011, 20:28:34 от lamerko »
Активен

antoniy

  • Управител
  • *
  • Неактивен Неактивен
  • Публикации: 723
    • http://antoniy.net/
Re:Една задачка - закачка!
« Отговор #3 -: 17.01.2011, 23:23:14 »

xyz++: всичко опира до интерпретация на ++х и х++

Всъщност всичко опира до приоритета на всички оператори. Аз мога да си измисля език, в който да объркам целия ни общоприет математически и софтуерен приоритет на операторите и там никой не може да каже какво ще се получи. Заради това се разглежда конкретен случай - конкретен език и компилатор/транслатор.
Активен
Too short signature limits.

Светослав Енков

  • Неактивен Неактивен
  • Публикации: 1864
    • Shark's Home Page
Re:Една задачка - закачка!
« Отговор #4 -: 19.01.2011, 00:41:17 »

Да, на практика Иван не указва изрично, че визира Javascript, но се подразбира с даденият от него пример за 'бърза проверка'. Интересно ми е, дали наистина JS спазва 100% всички приоритети на С++? По принцип знам, че уж ги 'наследява' от него, както и че тези в С++ са нещо като 'неявен стандарт'.

Лично аз избягвам да пиша такива двусмислени изрази. Най-вече, защото работя на няколко езика (Паскал, С/С++/C#, РНР) и понякога интересни фрагменти код ми се налага да ги 'портирам' от един на друг език за различните проекти. Ех, къде е Вавилонската рибка за кодерите?

М/у другото - аз избягвам да давам подобни задачки-закачки на студентите ми по С++, но съм виждал как в разни други ВУЗ-чета ги дават много смело и безотговорно по контролни и тестове... Искам да могат да мислят алгоритми, е това включва и разгадаване на подобен род неща, ама де да беше това най-важното, нали?

И оше, подобен род изрази, ако компилаторът не успее да ги опрости автоматично, как ли объркват процесора и редът на изпълнение на операциите? Горкичкото CPU! (не че го мисля)
« Последна редакция: 19.01.2011, 00:45:04 от Светослав Енков »
Активен

lamerko

  • Неактивен Неактивен
  • Публикации: 211
    • Моят блог
Re:Една задачка - закачка!
« Отговор #5 -: 19.01.2011, 01:28:58 »

Ами аз имах предвид, че горния пример ще сработи различно при различните компилатори. Например при PHP и C резултатите са 13 и 16, но при C# и JavaScript (Mozilla/Webkit) - 11 и 14. Сигурен съм, че би дал различен резултат на два различни компилатора на един и същи език  :) И точно поради това този пример наистина не е удачен.

Иначе разликите се получават не заради разликата в приоритетите на операциите, а просто в начина, по който се модифицират променливите.
Активен

antoniy

  • Управител
  • *
  • Неактивен Неактивен
  • Публикации: 723
    • http://antoniy.net/
Re:Една задачка - закачка!
« Отговор #6 -: 19.01.2011, 10:30:56 »

Иначе разликите се получават не заради разликата в приоритетите на операциите, а просто в начина, по който се модифицират променливите.

Моля, обясни за непосветените като мен, за да знаем от тук нататък.
Активен
Too short signature limits.

lamerko

  • Неактивен Неактивен
  • Публикации: 211
    • Моят блог
Re:Една задачка - закачка!
« Отговор #7 -: 19.01.2011, 12:32:56 »

Ами например ако a = 4, имаме израза: а+= (a++ + ++a); Това, което аз казвам е, че при PHP и C ще върне 16. Първо се изпълнява израза в скобите - неговия резултат е 10 - имаме 3 операции, 2-те с по-висок приоритет. При операцията ++а, а става 5. а++ се изпълнява, но все още не модифицирала променливата... когато идва операцията за събиране - модифицира променливата и събира. Така израза ВРЪЩА 10, НО СЪЩЕВРЕМЕННО променливата а = 6, а не на 4. Докато JavaScrip и C# няма да модифицират променливата извън израза в скобите.
Активен

Jack Johnson

  • Неактивен Неактивен
  • Публикации: 704
  • Хора, пазете си здравето! То няма цена!
Re:Една задачка - закачка!
« Отговор #8 -: 19.01.2011, 15:33:56 »

Ами например ако a = 4, имаме израза: а+= (a++ + ++a); Това, което аз казвам е, че при PHP и C ще върне 16. Първо се изпълнява израза в скобите - неговия резултат е 10 - имаме 3 операции, 2-те с по-висок приоритет. При операцията ++а, а става 5. а++ се изпълнява, но все още не модифицирала променливата... когато идва операцията за събиране - модифицира променливата и събира. Така израза ВРЪЩА 10, НО СЪЩЕВРЕМЕННО променливата а = 6, а не на 4. Докато JavaScrip и C# няма да модифицират променливата извън израза в скобите.

Now I'm officially impressed... изобщо не ми беше хрумнало да тествам кода на нещо друго, освен JavaScript!

В такъв случай даже ме е страх да питам какви ще са стойностите на a, b и c след изпълнение на следния код:

a = 3
b = 4
c = a+++b

Третият ред изглежда като грешка, но е напълно валиден!  :wink:

javascript:{var a = 3; var b = 4; var c = a+++b; alert("a = " + a + ", b = " + b + ", c = " + c);}


PS: Въпросът е дали се изпълнява това:

a++ + b
или това:

a + ++b
« Последна редакция: 19.01.2011, 15:44:27 от Иван Давидов »
Активен

Beginner

  • Неактивен Неактивен
  • Публикации: 67
  • May the source be with you
    • Begginer's web
Re:Една задачка - закачка!
« Отговор #9 -: 19.01.2011, 15:42:11 »

Иначе разликите се получават не заради разликата в приоритетите на операциите, а просто в начина, по който се модифицират променливите.
Как би обяснил тогава:
а += а++ + ++а   <=> 16
a = a + a++ + ++a  <=> 14
Активен
Понякога стоя и си мисля, а понякога само стоя.

lamerko

  • Неактивен Неактивен
  • Публикации: 211
    • Моят блог
Re:Една задачка - закачка!
« Отговор #10 -: 19.01.2011, 16:24:54 »

Иначе разликите се получават не заради разликата в приоритетите на операциите, а просто в начина, по който се модифицират променливите.
Как би обяснил тогава:
а += а++ + ++а   <=> 16
a = a + a++ + ++a  <=> 14

Ами втория вариант връща при мен 15, а не 14. Което затвърждава моята теза :)
Активен

Beginner

  • Неактивен Неактивен
  • Публикации: 67
  • May the source be with you
    • Begginer's web
Re:Една задачка - закачка!
« Отговор #11 -: 19.01.2011, 17:32:44 »

Иначе разликите се получават не заради разликата в приоритетите на операциите, а просто в начина, по който се модифицират променливите.
Как би обяснил тогава:
а += а++ + ++а   <=> 16
a = a + a++ + ++a  <=> 14

Ами втория вариант връща при мен 15, а не 14. Което затвърждава моята теза :)
Приоритетът на операциите определя начина на модификация на променливите:
postfix-increment/prefix-increment има по-висок приоритет. Също така има значение и асоциативността на операторите
Събирането например е ляво-асоциативна операция, докато prefix-a e дясно.

Разликата идва от това че += е дясно-асоциативна операция а = е ляво-асоциативна (http://cs.smu.ca/~porter/csc/ref/cpp_operators.html)
Активен
Понякога стоя и си мисля, а понякога само стоя.

А.Пенев

  • Неактивен Неактивен
  • Публикации: 157
    • www.alexander-penev.info
Re:Една задачка - закачка!
« Отговор #12 -: 20.01.2011, 10:53:55 »

Тази дискусия според мен още веднъж показва защо тези оператори трябва да се забранят със закон  :wink:

Който иска да пише неразбираеми, заплетени и не работещи програми може да се справи успешно и без тях.

Според мен тези оператори са артефакти от древното минало, когато един байт по-малко в сорс-кода е бил от значение и хората не са могли да си направят като хората компилатора да оптимизира в тези случаи (те и сега май още не могат  :wink: )
Активен
А.Пенев

Светослав Енков

  • Неактивен Неактивен
  • Публикации: 1864
    • Shark's Home Page
Re:Една задачка - закачка!
« Отговор #13 -: 20.01.2011, 11:31:57 »

Да, аз ги избягвам наистина тези оператори, защото не опростяват нищо и не се ускоряват програмите. Новите компилатори оптимизират доста, повече отколкото съм мислел дори, но и новите процесори са 'манджа с грозде' с тия виртуални инструкции (CISC to RISC conversion, Out-of-order execution, Hyper-Threading), така че няма смисъл, освен в краен брой много редки случаи - драйвери, обработки на изображения и критични Real-Time приложения, където пък не се използват х86 по принцип.

За задачка-закачка си са супер, да! За реална работа - не!
Активен