argon bulletin board
Факултети => Факултет по математика и информатика => Темата е започната от: Jack Johnson в 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"?
-
Интересен код.
4 += (4 + 6), което е равно на 14 е отговорът, показан от browser-а.
Като го компилирам с gcc, става друго.
a += (4 + 6), понеже след ++ a=6, крайното е 16.
Може би реализациите са различни.
-
11; 14;
Или:
3 += (3++ + 4) = 3 += 8 = 11;
4 += (4++ + 5) = 4 += 10 = 14;
И какъв е смисъла да слагаш решението :)
ed:
xyz++: всичко опира до интерпретация на ++х и х++
-
xyz++: всичко опира до интерпретация на ++х и х++
Всъщност всичко опира до приоритета на всички оператори. Аз мога да си измисля език, в който да объркам целия ни общоприет математически и софтуерен приоритет на операторите и там никой не може да каже какво ще се получи. Заради това се разглежда конкретен случай - конкретен език и компилатор/транслатор.
-
Да, на практика Иван не указва изрично, че визира Javascript, но се подразбира с даденият от него пример за 'бърза проверка'. Интересно ми е, дали наистина JS спазва 100% всички приоритети на С++? По принцип знам, че уж ги 'наследява' от него, както и че тези в С++ са нещо като 'неявен стандарт'.
Лично аз избягвам да пиша такива двусмислени изрази. Най-вече, защото работя на няколко езика (Паскал, С/С++/C#, РНР) и понякога интересни фрагменти код ми се налага да ги 'портирам' от един на друг език за различните проекти. Ех, къде е Вавилонската рибка за кодерите?
М/у другото - аз избягвам да давам подобни задачки-закачки на студентите ми по С++, но съм виждал как в разни други ВУЗ-чета ги дават много смело и безотговорно по контролни и тестове... Искам да могат да мислят алгоритми, е това включва и разгадаване на подобен род неща, ама де да беше това най-важното, нали?
И оше, подобен род изрази, ако компилаторът не успее да ги опрости автоматично, как ли объркват процесора и редът на изпълнение на операциите? Горкичкото CPU! (не че го мисля)
-
Ами аз имах предвид, че горния пример ще сработи различно при различните компилатори. Например при PHP и C резултатите са 13 и 16, но при C# и JavaScript (Mozilla/Webkit) - 11 и 14. Сигурен съм, че би дал различен резултат на два различни компилатора на един и същи език :) И точно поради това този пример наистина не е удачен.
Иначе разликите се получават не заради разликата в приоритетите на операциите, а просто в начина, по който се модифицират променливите.
-
Иначе разликите се получават не заради разликата в приоритетите на операциите, а просто в начина, по който се модифицират променливите.
Моля, обясни за непосветените като мен, за да знаем от тук нататък.
-
Ами например ако a = 4, имаме израза: а+= (a++ + ++a); Това, което аз казвам е, че при PHP и C ще върне 16. Първо се изпълнява израза в скобите - неговия резултат е 10 - имаме 3 операции, 2-те с по-висок приоритет. При операцията ++а, а става 5. а++ се изпълнява, но все още не модифицирала променливата... когато идва операцията за събиране - модифицира променливата и събира. Така израза ВРЪЩА 10, НО СЪЩЕВРЕМЕННО променливата а = 6, а не на 4. Докато JavaScrip и C# няма да модифицират променливата извън израза в скобите.
-
Ами например ако 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
-
Иначе разликите се получават не заради разликата в приоритетите на операциите, а просто в начина, по който се модифицират променливите.
Как би обяснил тогава:
а += а++ + ++а <=> 16
a = a + a++ + ++a <=> 14
-
Иначе разликите се получават не заради разликата в приоритетите на операциите, а просто в начина, по който се модифицират променливите.
Как би обяснил тогава:
а += а++ + ++а <=> 16
a = a + a++ + ++a <=> 14
Ами втория вариант връща при мен 15, а не 14. Което затвърждава моята теза :)
-
Иначе разликите се получават не заради разликата в приоритетите на операциите, а просто в начина, по който се модифицират променливите.
Как би обяснил тогава:
а += а++ + ++а <=> 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)
-
Тази дискусия според мен още веднъж показва защо тези оператори трябва да се забранят със закон :wink:
Който иска да пише неразбираеми, заплетени и не работещи програми може да се справи успешно и без тях.
Според мен тези оператори са артефакти от древното минало, когато един байт по-малко в сорс-кода е бил от значение и хората не са могли да си направят като хората компилатора да оптимизира в тези случаи (те и сега май още не могат :wink: )
-
Да, аз ги избягвам наистина тези оператори, защото не опростяват нищо и не се ускоряват програмите. Новите компилатори оптимизират доста, повече отколкото съм мислел дори, но и новите процесори са 'манджа с грозде' с тия виртуални инструкции (CISC to RISC conversion, Out-of-order execution, Hyper-Threading), така че няма смисъл, освен в краен брой много редки случаи - драйвери, обработки на изображения и критични Real-Time приложения, където пък не се използват х86 по принцип.
За задачка-закачка си са супер, да! За реална работа - не!