Skip to content

L value&R value 左值与右值

In C, every expression evaluates to either an lvalue or an rvalue. Understanding the difference is crucial for understanding memory management, pointers, and fixing compiler errors like "lvalue required as left operand of assignment."

1. The Simple Rule of Thumb

Historically, the names come from the assignment operator (=):

  • L-value: An expression that can appear on the Left side of an assignment.

  • R-value: An expression that can only appear on the Right side of an assignment.

L-value=R-value;L-value=R-value;

2. Deep Dive: L-value (Locator Value)

An lvalue refers to an object that persists in memory and occupies an identifiable location (an address).

  • Think: "L" stands for Location.

  • Key Characteristic: You can take its address using the & operator.

  • Usage: It designates a storage region so the program can save data there.

Examples of L-values:

  • Variables: int x; (x is an lvalue).

  • Array elements: arr[0] is an lvalue.

  • Dereferenced pointers: *ptr is an lvalue (it points to a location).

Note on Modifiability:
Not all lvalues can be modified. A const variable is an lvalue (it has a memory address), but it is a non-modifiable lvalue. You cannot assign a new value to it, but you can still take its address.


3. Deep Dive: R-value (Value of an Expression)

An rvalue is a temporary value that does not persist in memory beyond the expression that uses it.

  • Think: "R" stands for Read-only value or the actual data.

  • Key Characteristic: You cannot take its address using &.

  • Usage: It provides the data to be stored in an lvalue.

Examples of R-values:

  • Literals: 5, 'a', "hello" (string literals are a special exception, but treat numbers as rvalues).

  • Math results: x + 5 (the result is temporary).

  • Function returns: sqrt(4.0) returns a value, not a memory location.


4. How They Interact

The Conversion (L-value to R-value)

An lvalue can be used as an rvalue. This happens when the compiler reads the data stored at a memory address to use it in a calculation.

codeC

int x = 10; // 'x' is an lvalue.
int y = x;  // Here, 'x' is used as an rvalue (we read its contents).

The Forbidden (R-value to L-value)

An rvalue can never be used as an lvalue. You cannot assign data to something that has no memory address.

codeC

10 = x;       // ERROR: 10 is an rvalue. You can't assign TO a number.
(x + y) = 20; // ERROR: (x+y) is a temporary result. It has no permanent address.

5. Code Examples

✅ Valid Code

codeC

int a = 10;        // 'a' is lvalue, '10' is rvalue.
int *p = &a;       // '&a' requires 'a' to be an lvalue.
*p = 20;           // '*p' is an lvalue (location pointed to by p).
int b = a + 5;     // 'a' acts as rvalue here. 'a + 5' is an rvalue.

❌ Invalid Code (Common Errors)

int a = 10;

// Error: lvalue required as left operand of assignment
5 = a;             

// Error: lvalue required as left operand of assignment
(a + 1) = 20;      

// Error: lvalue required as unary '&' operand
int *p = &(a + 1); // You cannot take the address of a temporary calculation.

Summary Table

Feature L-value R-value
Meaning Locator Value (Memory Address) Data Value (Content)
Position in x = y Left (or Right) Right Only
Has Memory Address? Yes No (usually stored in registers/temporary)
Can use & operator? Yes No
Example x, arr[i], *ptr 100, x + y, func()