Это касается lvalues и rvalues в C и C ++.
В языке программирования C операторы предварительного увеличения и последующего увеличения возвращают значения, а не значения. Это означает, что они не могут быть слева от =
оператора присваивания. Оба эти утверждения приведут к ошибке компилятора в C:
int a = 5;
a++ = 2; /* error: lvalue required as left operand of assignment */
++a = 2; /* error: lvalue required as left operand of assignment */
Однако в C ++ оператор предварительного увеличения возвращает значение l , а оператор постинкремента возвращает значение r. Это означает, что выражение с оператором предварительного увеличения может быть размещено слева от =
оператора присваивания!
int a = 5;
a++ = 2; // error: lvalue required as left operand of assignment
++a = 2; // No error: a gets assigned to 2!
Теперь, почему это так? Постинкремент увеличивает переменную и возвращает переменную, которая была до того, как произошло увеличение. На самом деле это просто ценность. Прежнее значение переменной a копируется в регистр как временное, а затем увеличивается на a. Но прежнее значение a возвращается выражением, это rvalue. Он больше не представляет текущее содержимое переменной.
Предварительный инкремент сначала увеличивает переменную, а затем возвращает переменную такой, какой она стала после того, как произошло увеличение. В этом случае нам не нужно сохранять старое значение переменной во временном регистре. Мы просто получаем новое значение переменной после его увеличения. Таким образом, предварительное приращение возвращает lvalue, оно возвращает саму переменную a. Мы можем использовать присвоение этого lvalue чему-то другому, это похоже на следующее утверждение. Это неявное преобразование lvalue в rvalue.
int x = a;
int x = ++a;
Поскольку предварительное приращение возвращает lvalue, мы также можем присвоить ему что-то. Следующие два утверждения идентичны. Во втором присваивании сначала увеличивается значение a, затем его новое значение перезаписывается на 2.
int a;
a = 2;
++a = 2; // Valid in C++.