| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > .NET для новичков > int i = 0; i += i++; |
| Автор: Kuvaldis 2.10.2007, 16:08 | ||
| Вот сходил я, С++-ник, на собеседование по .NET И задали мне вопрос:
C точки зрения С++ получается 1, что я и скачал, но правильный ответ - 0 Я не совсем понимаю, почему. Был бы рад услышать объяснение СУВ, Kuvaldis |
| Автор: ivashkanet 2.10.2007, 16:20 |
| Kuvaldis, ИМХО: сразу посылаешь их наф с таким вопросом и говоришь, что как захотели разработчики компилятора, так и будет! Как получить ноль?.. Могу предположить, что в i += i++: 1) Берется сначала значение i (ноль) 2) Происходит инкремент (i=1) 3) Выполняется операция увеличения i (шарп собака, сохраняет старое значение i и берет его) на значение справа (ноль из первой строки). В общем еще один пример UB Удачи ;-) |
| Автор: ivashkanet 2.10.2007, 17:01 | ||
| Еще момент: эта строчка ведь эквивалентна строчке:
В результате которой никто не сомневается.... |
| Автор: ivashkanet 2.10.2007, 17:48 |
Пусть будет так ;-) (у меня есть вопросы и к твоему и к моему объяснению Это выражение можно и без дебагера подсчитать (о чем я и говорил) |
| Автор: Kuvaldis 2.10.2007, 18:42 | ||
tol05,
А откуда здесь временная переменная? Я пытаюсь разницу с С++ понять в данном вопросе. |
| Автор: NikeDeForest 2.10.2007, 19:01 |
| [offtopic] А там из спичек ничего не просили собрать? Чем они обоснуют такой вопрос? Тем, что такое можно встретить в коде их разработчиков? Тогда беги от туда, таким го*но месить, а не код писать. [/offtopic] |
| Автор: tol05 2.10.2007, 21:46 | ||||||
выражение
для меня означает: 1. возьми i 2. увеличь его на значение, равное i 3. присвой результат тому же i 4. после увеличения, инкрементируй "значение, равное i" (но не i) здесь смешались понятия постфиксной формы инкремента и операндов операций (все-таки то, что стоит слева от знака "=" - не то же самое, что стоит справа Непонятно? у меня тоже Проще всего разобраться как будут выглядеть операции в ассемблере. В ячейку, содержащую i, записывается результат сложения двух регистров. В регистр А записывается значение из ячейки i, в регистр В - такое же значение. Происходит сложение значений двух регистров, результат записывается в ячейку i и только потом значение регистра В инкрементируется. если бы было написано так:
тогда да, было бы увеличение i через правый операнд (который в данный момент равен i, но им не является). А потом - инкремент i. Потому что компилятор расшифровывает одинокое выражение i++ как i=i+1. Kuvaldis, я думаю, тебе стоит почитать стандарт http://www.ecma-international.org/publications/standards/Ecma-334.htm, раздел 14.5.9 (postfix) и 14.6.5 (prefix) Там написано, что могут хотеть , а чего - нет NikeDeForest, это прекрасный вопрос, для проверки глубины понимания синтаксических конструкций. Я как-то на похожем вопросе засыпался. Тем более, ИМХО, бежать нужно не "оттуда", а "туда". Нужно считать расход памяти на операции потому что... В моем коде такое тоже можно встретить, и чем больше проходит времени, тем все чаще и чаще |
| Автор: NikeDeForest 3.10.2007, 05:52 | ||||
Код не должен содержать в себе такие конструкции, код должен быть легко и удобочитаемым.
Это микрооптимизация, которая должна быть обоснованна и документирована. При этом оптимизацию не проводят на первоначальном этапе конструирования, она проводится не на протяжении всего кода, а на критическом участке. А что по поводу того, что у тебя это почти везде подряд попадается, то без обид конечно, но имхо, это пижонство, которое не оценит тот, кто будет читать твой код. К тому же оптимизация на .НЕТ - это штука ненадежная. Хочу привести пример, но пора уже бежать. Через пару часов попробую, если не забуду. |
| Автор: Alek86 3.10.2007, 07:29 | ||
| эээ ну в С++ стандарте насчет подобных примеров было ясно сказано, что будет неопределенность и все на форумах давно обматерили тех, кто на собеседовании задает подобные вопросы. есть у кого ссылка на шарповский "стандарт", где эта ситуация обговорена? ато и здесь может стать анекдотичный вопрос. чему будет равно i:
|
| Автор: Kuvaldis 3.10.2007, 08:51 | ||||||
Alek86,
Как раз по поводу С++ здесь все понятно ИМХО По приоритету операции сначала идет ++ а потом +=. Причем никаких временных переменных нет. Поэтому и получается 1 Если проверять код
то получим 2, что говорит о том, что используется одна область памяти А вот про это
tol05, Сиба за ссылку и объяснения, буду читать. Мое ИМХО: так писать низзя Еще в "Практике программирования" Керниган сказал, что размер в ущерб понятности ставить не желательно |
| Автор: tol05 3.10.2007, 10:07 | ||||||||||
я не виноват, если читать мой код посадят человека, не знающего синтаксиса языка. Это проблема тех, кто принял его на работу. Без обид.
Нужно читать любой код и читать правильно. Поэтому я "за" за существование таких вопросов в тесте. Нельзя так писать? а так
или
можно? Это читаемо? Просто инкремент и декремент выполняются быстрее, чем присваивание. Но вряд ли это кого-от беспокоит, кроме меня. Вряд ли Керниган имел в виду простейшие констукции
Да... И напишите письмо в команду разработчиков .Net 2.0, чтобы убрали из новой версии анонимные методы, итераторы и генерики. |
| Автор: Rodman 3.10.2007, 10:19 | ||||
i++ - инкремен происходит после использования переменной! тогда и получается что прибавляется 0,
|
| Автор: Alek86 3.10.2007, 11:16 | ||
я бы так не утверждал категорично... в сях есть такая вещь, как "точка следования", и по стандарту += не входит в те операторы, после которых она (точка) ставится. в С++ результат этого i += ++i; выражения неопределен потому и нужно посмотреть на стандарт C#, что там насчет этого говорится. |
| Автор: skyboy 3.10.2007, 11:35 | ||
http://alenacpp.blogspot.com/2005/11/sequence-points.html
а где можно посмотреть стандарт по С#? Не подскажешь? |
| Автор: Deja_Vu 3.10.2007, 11:36 | ||||||||
|
| Автор: skyboy 3.10.2007, 11:44 |
http://www.ecma-international.org/publications/standards/Ecma-334.htm, 2.5 Мб Вот только с английским не настолько дружу, чтоб сходу найти нужный раздел... |
| Автор: Alek86 3.10.2007, 13:27 |
| пара оффтопов Deja_Vu, насчет С++ еще раз - там неопределенность! если кто-то будет говорить иначе, посылай читать стандарт skyboy, насчет ссылки про точки следования - сам почитываю ее блог иногда |
| Автор: ivashkanet 3.10.2007, 13:32 |
Меня интересует почему в С++ здесь единица, а не ноль? Добавлено через 43 секунды Все потому что неопределённость? |
| Автор: Deja_Vu 3.10.2007, 13:35 | ||||||
я что-то увтерждаю?! ((- Я просто привожу результат компиляция на VS 2008. В MSDN и в спецификации ничего по этому поводу найти не могу... остается всего одно предположение i = i + i++; 1. вычисляется выражение i + i 2. выполняется операция i++ 3. выполняется присваивание i = результату(1) Добавлено @ 13:44 да уж ...
|
| Автор: tol05 3.10.2007, 14:01 |
| нашел неплохой источник информации по данной проблеме http://www.google.com/search?hl=en&rlz=1T4GGLJ_enUA238UA238&q=increment+C%2B%2B+C%23+differences |
| Автор: Deja_Vu 3.10.2007, 14:17 |
| sorry -)) |
| Автор: Fazil6 3.10.2007, 14:24 |
не в С++, а в программе, скомпиллированной определенным компиллятором определенной версии. Как сделали разработчики порядок и логику вычислений, так ты и получил. На другой версии компиллятора ты можешь получить другое значение, например 24 и ошибкой это не будет. Как говорится что написал - то и получил. Написал выражение правила вычисления которого не существует - то и получай в результате что угодно. |
| Автор: Deja_Vu 3.10.2007, 14:30 | ||
thx to tol05 оказываетя мое предположение верно. http://weblogs.asp.net/kennykerr/archive/2006/03/29/Increment-differences-in-C_2B002B00_-and-C_2300_.aspx |
| Автор: ivashkanet 3.10.2007, 14:52 | ||||
Я это знаю
Это я и имел ввиду Спасибо ;-) |
| Автор: Alek86 3.10.2007, 16:01 |
[/quote=Как раз с той ссылки]At the end of the day the C# compiler results in a value of 1 and the C++ compiler results in a value of 2. Neither is right, neither is wrong and both are undefined.[/quote] так что не совсем верно а в шарпе в стандарте я чето не нашел никаких правил :(. думается мне, что там все считается по-порядку к тому же я знаю только одну версию компилятора C#, написанную майкрософтом ЗЫ. кстати, под линух компилятор (а не среда исполнения Mono) существует? |
| Автор: Deja_Vu 3.10.2007, 23:09 | ||||
ну ... что правильно, и не правильно не мне решать ... но то как действует компилятор C# от MS описано то мною верно -)) |