В общем случае, когда оператор присваивания есть, левый операнд должен
быть переменной, а не выражением ...
Левый операнд оператора присваивания является всегда выражением. Ограничение состоит в том, что это должно быть lvalue , которое (немного упрощает) выражение, обозначающее объект.
Простейшим случаем lvalue является имя объявленного объекта / переменной, например:
int n;
n = 42;
n
- это выражение, в частности lvalue, которое обозначает объект с именем n
.
В вашем примере у вас есть:
*y++ = *z++;
Приоритет оператора говорит, что оператор ++
связывается более тесно, чем оператор *
, поэтому это эквивалентно:
*(y++) = *(z++);
y++
и z++
не являются значениями - это выражения, которые дают значения указателя, но они не обозначают никаких объектов. Но унарный оператор *
дает вам lvalue, даже если его операнд не является lvalue. y++
возвращает значение указателя, а *(y++)
- объект, на который указывает указатель.
Стандарт C не использует термин «переменная» в этом смысле. В нем говорится о объектах , которые могут быть или не быть объявлены объектами с простыми именами. an_object
, *pointer_value
, array[index]
и structure_object.member
относятся к объектам и могут отображаться слева от назначения.