#c #compilation
#c #Сборник
Вопрос:
Я наткнулся на следующее утверждение:
Умный компилятор может распознать, что
x = x 1
может обрабатываться так же, какx
.
Почему здесь вместо оператора post-fix используется префиксный оператор (или любой другой, если это не имеет значения)? Например, если бы у меня был следующий цикл:
while (x < 10) {
...
x ; // wouldn't this be the same as doing x here?
}
Какой был бы случай, который показывает, как x = x 1
эквивалентно x
и нет x
?
Ответ №1:
Вот простой пример. Предположим, у вас есть что-то вроде этого:
a = (x = x 1);
Это было бы эквивалентно
a = x;
но не для
a = x ;
Ответ №2:
Какой был бы случай, который показывает, как x = x 1 эквивалентно x, а не x ?
Любой случай, когда используется значение выражения.
Один пример: if((x = x 1) < 10)
эквивалентно if( x < 10)
, но нет if(x < 10)
.
Ответ №3:
Не имеет значения, используете ли вы i
или i
как отдельное выражение. Единственное различие заключается в значении выражения, которое не используется в обоих случаях.
Вы также можете написать i = 1
или i = i 1
, и компилятор должен сгенерировать один и тот же код для всех 4 вариантов (с включенной оптимизацией).
Если используется значение выражения, i = i 1
и i = 1
эквивалентны i
и все имеют обновленное значение, тогда i
как имеет исходное значение i
.
Комментарии:
1. «Неиспользуемый в обоих случаях» или «не используется ни в одном случае» было бы лучше. Формулировка «не используется в обоих случаях» предполагает, что оно используется или, по крайней мере, может использоваться в одном из случаев.
2. @JohnBollinger: спасибо, действительно, была третья возможная интерпретация, которая была непреднамеренной 🙂
Ответ №4:
Выражение i
возвращает значение i
перед его увеличением, в то время как выражение i
возвращает значение i
после увеличения.
Например:
int i = 1;
int j = i ; // j now equals 1, i equal 2
И i
int i = 1;
int j = i; // j and i both equal 2.
Выражение x = x 1
возвращает значение x
после увеличения, а не перед ним, поэтому оно эквивалентно i