Евгений
Евгений | Репутация: 108 (Кандидат) 26 марта 2009 в 10:19
Уважаемые гуру, не подскажите начинающему, почему результат выражения x=7, x*=x++ равен 50, а не 56?
По идее, после выполнения ++, x должен иметь значение 8, но отдать операции *= значение 7, и в итоге должно получиться x=8*7, но не получается
Михаил Тумайкин
Михаил Тумайкин | Репутация: 129 (Кандидат) 26 марта 2009 в 10:48

x*=x++; эквивалентно
x = x * x; x++;
x++ - инкремент после вычисления выражения
++x - инкремент до

Иван Коструба
Иван Коструба | Репутация: 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.