Евгений | Репутация: 108(Кандидат)
26 марта 2009 в 10:19
Уважаемые гуру, не подскажите начинающему, почему результат выражения x=7, x*=x++ равен 50, а не 56? По идее, после выполнения ++, x должен иметь значение 8, но отдать операции *= значение 7, и в итоге должно получиться x=8*7, но не получается
Иван Коструба | Репутация: 106(Кандидат)
26 марта 2009 в 10:51
Все дело в приоритете операций. Операция инкремента имеет приоритет ниже, чем умножение с присваиванием. Фактически в приведенном коде происходит так:
(x *= x)++ // 7 * 7 и увеличивается на 1.
Выхода два: либо расставить скобки, явно указав последовательность выполнения операций, либо написать:
x *= ++x;
Виктор Кушанов | Репутация: 111(Кандидат)
26 марта 2009 в 11:08
постфиксный ++ работает после выполнения операции. эта запись переводится как x = (x * x)++.Это хорошо видно в ассемблере.
UMain.cpp.2029: int x = 7;00423138 C745F407000000 mov [ebp-$0c],$00000007UMain.cpp.2030: x *= x++;0042313F 8B45F4 mov eax,[ebp-$0c]00423142 0FAF45F4 imul eax,[ebp-$0c]00423146 8945F4 mov [ebp-$0c],eax00423149 FF45F4 inc dword ptr [ebp-$0c]
Иван Сапуглецев | Репутация: 111(Кандидат)
26 марта 2009 в 21:09
Дело вовсе не в приоритете операций (тем более, что инкремент ++ имеет гораздо более высокий приоритет, чем операция присваивания с умножением). В данном случае инкремент постфиксный (стоит после операнда x), а это значит, что он будет выполняться лишь после того, как x будет использован (в операции присваивания с умножением). Лучше всего это наблюдать у разноимённых переменных: пусть x==7, y==7, нужно вычислить x*=y++. В этом случае y, равный 7, будет передан операции *= и лишь после этого увеличен на 1 операцией ++.
Для того чтобы избавиться от такого эффекта, можно, как уже было описано, использовать разне варианты. А вот префиксный инкремент (++x) в данном случае даст ответ 64. Т.е. x будет увеличен на 1, после чего операция *= будет выполняться над уже этим изменённым значением x.
x*=x++; эквивалентно
x = x * x; x++;
x++ - инкремент после вычисления выражения
++x - инкремент до