Значение L vs R в C

Я отвечаю на вопрос учебника из этого учебника .

Я узнаю о указателях в C и столкнулся с l-значениями и значениями r. Из моего понимания:

l-values are values that are defined after they are executed (++x) r-values are values that are not defined after they are executed (x++) 

Это правильно?

Вопрос, на который я хотел ответить (с моими попытками):

 a) Which of the following C expressions are L-Values? 1. x + 2 Not a L value 2. &x Is a L value 3. *&x Is a L value 4. &x + 2 Not a L value 5. *(&x + 2) Is a L value 6. &*y Is a L value b) Is it possible for a C expression to be a L-value but NOT a R-value? Explain I've read that a L value can be a R value but not vice versa. I can't think of an example of something being an L value but not a R value. c) Is &(&z) ever legal in C? Explain Assuming this is not legal since a memory address doesn't have its own memory address? 

Я близко? Спасибо

l-значения – это значения, которые определены после их выполнения ( ++x ). r-значения – это значения, которые не определены после их выполнения ( x++ )

Нет, это неправильно.

Слова «lvalue» и «rvalue» (это то, как их задает стандарт C) имеют долгую историю. Термины взяты из «l» для «left» и «r» для «right», ссылаясь на левую и правую части задания.

В некоторых контекстах выражение может быть либо оценено для его lvalue, либо оценено для его rvalue . Учитывая эти определения терминов, «rvalue» – это то, что вы обычно считаете значением выражения; оценка 2+2 дает 4 . Оценка выражения для его lvalue означала определение того, к какому объекту он относится. Например, учитывая:

 int x; x = 2 + 2; 

правая часть задания, 2 + 2 будет оцениваться за его значение r, давая 4 , а левая сторона будет оцениваться по ее lvalue, что означает определение объекта, к которому он относится. (Значение r выражения не оценивается, значение, ранее сохраненное в x , если оно не используется).

Стандарт C определяет их по-разному. В C значение l не является значением; это своего рода выражение. В частности, цитируя стандарт ISO C 2011 года, раздел 6.3.2.1:

Lvalue – выражение (с типом объекта, отличным от void), который потенциально обозначает объект; если lvalue не назначает объект при его оценке, поведение не определено.

(Слово «потенциально» было добавлено, чтобы охватывать такие случаи, как *ptr , где ptr – объект-указатель, если ptr == NULL то *ptr настоящее время не обозначает объект, но он все еще является lvalue. Вы всегда можете определить при компиляции время, если данное выражение является lvalue или нет. Ранее выпуски стандарта C имели ошибочные определения для lvalue .)

Таким образом, значение lvalue в C является выражением, которое обозначает объект. Вы можете думать об этом как о выражении, которое может появиться в левой части задания, хотя это не совсем точно; например, имя объекта const не может быть в LHS присвоения, но оно все еще является lvalue. (Как вы можете видеть, сглаживание точного и последовательного определения для lvalue может быть сложным.)

Ни x++ ни ++x не является lvalue в C.

Стандарт C не использует термин rvalue, не упоминая его в одной сноске:

То, что иногда называют «rvalue», в этом международном стандарте описывается как «значение выражения».

Таким образом, поскольку C определяет термины, lvalue является своего рода выражением (что-то, что существует в исходном коде C), но rvalue является результатом оценки выражения (что-то, что существует во время выполнения программы).

(C ++ имеет разные правила и несколько других classов lvalue-подобных вещей, включая glvalues и т. Д. Я не буду вдаваться в это здесь.)