在C语言中,lvalue和rvalue的区别历史上是为了确定哪些表达式可以应用赋值运算符。Lvalue(左值)表示一个占据特定内存位置的对象,可以对其应用取地址操作(&)。Rvalue(右值)是一个没有特定地址的临时值。理解这一点对于理解赋值、函数参数传递以及编译器优化是很重要的。
当尝试对rvalue执行仅针对lvalue允许的操作(例如赋值)时,问题就会出现,反之亦然。这可能导致编译错误或在执行阶段出现不明显的错误。
解决方案在于明确理解lvalue和rvalue的使用上下文。示例:
int x = 5; int y; y = x; // x是lvalue和rvalue,y是lvalue y = x + 1; // x + 1是rvalue(无法取地址) // &x是正确的,&(x + 1)是错误的
关键特性:
可以对任何表达式取地址吗,譬如表达式(x + y)?
不可以,只有lvalue才有地址。例如,表达式(x + y)是rvalue。
int z = 3, y = 7; int *p = &(z + y); // 编译错误
尝试向常量赋值(例如,5 = x)会发生什么?
会发生编译错误,因为字面量5是rvalue,不能作为lvalue。
5 = x; // 错误:左操作数不是lvalue
函数可以返回lvalue吗?
普通函数返回rvalue,但如果返回引用(例如在C++中),则是lvalue。在C中只允许返回rvalue。
int foo() { int x = 5; return x; } // 返回rvalue
程序员试图对临时结果表达式(a + b)取地址:
int *p = &(a + b);
优点:
缺点:
程序员有意识地区分lvalue和rvalue。仅在语法和语义允许的地方使用值:
int x = 7; int *p = &x; // 正确
优点:
缺点: