📜  C语言中的左值和右值

📅  最后修改于: 2021-05-25 22:04:37             🧑  作者: Mango

L值 “ l值”是指标识对象的内存位置。 l值可能显示为赋值运算符(=)的左侧或右侧。 l值通常表示为标识符。

涉及可修改位置的表达式称为“可修改l值”。可修改的左值不能具有数组类型,不完整类型或具有const属性的类型。为了使结构和联合成为可修改的左值,它们不得具有带有const属性的任何成员。标识符的名称表示存储位置,而变量的值是存储在该位置的值。

如果标识符引用一个内存位置并且其类型是算术,结构,联合或指针,则它是可修改的左值。例如,如果ptr是指向存储区域的指针,则* ptr是可修改的l值,用于指定ptr指向的存储区域。

在C语言中,该概念被重命名为“定位器值” ,并引用了定位(指定)对象的表达式。 l值是以下值之一:

  1. 任何类型的变量的名称,即整数,浮点,指针,结构或联合类型的标识符。
  2. 下标([])表达式,其结果不等于数组。
  3. 不引用数组的一元间接(*)表达式
  4. 括号中的l值表达式。
  5. const对象(不可修改的l值)。
  6. 如果不是函数指针,则通过指针进行间接寻址的结果。
  7. 通过指针(->或。)进行成员访问的结果
// declare a an object of type 'int'
int a;
 
// a is an expression referring to an
// 'int' object as l-value
a = 1;
  
int b = a; // Ok, as l-value can appear on right
 
// Switch the operand around '=' operator
9 = a;
 
// Compilation error:
// as assignment is trying to change the
// value of assignment operator

R值:r值”是指存储在内存中某个地址的数据值。 r值是无法为其分配值的表达式,这意味着r值可以出现在赋值运算符(=)的右侧,但不能出现在左侧。

// declare a, b an object of type 'int'
int a = 1, b;
 
a + 1 = b; // Error, left expression is
           // is not variable(a + 1)
 
// declare pointer variable 'p', and 'q'
int *p, *q; // *p, *q are lvalue
 
*p = 1; // valid l-value assignment
 
// below is invalid - "p + 2" is not an l-value 
// p + 2 = 18; 
 
q = p + 5; // valid - "p + 5" is an r-value
 
// Below is valid - dereferencing pointer
// expression gives an l-value
*(p + 2) = 18;
 
p = &b; 
 
int arr[20]; // arr[12] is an lvalue; equivalent
              // to *(arr+12)
              // Note: arr itself is also an lvalue
 
struct S { int m; };
 
struct S obj; // obj and obj.m are lvalues
 
// ptr-> is an lvalue; equivalent to (*ptr).m
// Note: ptr and *ptr are also lvalues
struct S* ptr = &obj;

注意:一元&(address-of)运算符需要一个左值作为其操作数。也就是说,仅当n是左值时,&n是有效表达式。因此,诸如&12之类的表达式是错误的。同样,12没有引用对象,因此它是不可寻址的。例如,

// declare a as int variable and
// 'p' as pointer variable
int a, *p;
 
p = &a; // ok, assignment of address
        // at l-value
 
&a = p;    // error: &a is an r-value
 
int x, y;
 
(  x < y ? y : x) = 0; // It's valid because the ternary
                  // expression preserves the "lvalue-ness"
                 // of both its possible return values

参考:
https://msdn.microsoft.com/zh-CN/library/bkbs2cds.aspx

想要从精选的最佳视频中学习和练习问题,请查看《基础知识到高级C的C基础课程》。