c语言和c++里面的左值、右值

发布时间:2026/10/27 18:59:08
c语言和c++里面的左值、右值

可以记:

C 里面有左值概念,但“右值体系”是 C++ 为了对象生命周期和移动语义扩展出来的。

简单说:C 语言里面有“左值(lvalue)”这个概念,但没有 C++ 那么完整的“左值/右值体系”。

C++ 的左值、右值概念是从 C 继承来的,但后来扩展得非常复杂,尤其是为了支持移动语义(move semantics)和右值引用(&&)。


1. C 语言里的左值(lvalue)

C 语言标准里有 lvalue。

简单理解:

左值:表示一个有存储位置(地址)的对象,可以出现在赋值号左边。

例如:

inta=10;a=20;

这里:

  • a是左值
  • 20是常量,不是左值

因为:

&a

可以取得地址:

printf("%p",&a);

说明a有内存位置。


再比如:

intarr[10];arr[3]=100;

arr[3]是左值。

因为它代表数组中的一个真实内存位置。


2. C 里面有没有右值(rvalue)?

严格来说:

C 标准没有正式定义 rvalue 这个术语。

但是 C 程序员通常会这样理解:

不能作为左值使用的表达式,就是“右值”。

例如:

inta;a=1+2;

这里:

1+2

产生一个临时结果,没有独立存储位置。

所以通常称为:

右值

例如:

intx;x=x+1;

右边:

x + 1

是一个计算结果。

它没有地址:

&(x+1)// 错误

所以不是左值。


3. C 和 C++ 最大区别

C:

大概只有:

左值 | +-- 非左值(通常叫右值)

例如:

inta;a=5;
a 左值 5 非左值 a+5 非左值

C++:

后来发展成:

表达式类别 expression | -------------------- | | glvalue rvalue | | -------- ---------- | | | | lvalue xvalue prvalue

也就是:

左值 纯右值 将亡值

4. 为什么 C++ 要搞这么复杂?

主要为了:

std::move()

和移动构造。

例如:

std::string a="hello";std::string b=a;

复制:

a | 复制数据 | b

比较慢。

C++11:

std::string b=std::move(a);

告诉编译器:

a 不需要保留了,可以把内部资源直接搬走。

这需要区分:

  • 还有用的对象(lvalue)
  • 可以被移动的临时对象(xvalue)

5. 一个 C/C++ 对比例子

C:

inta=10;int*p=&a;

可以:

a | 地址

所以:

a 是左值

C++:

inta=10;int&&b=20;

这里:

20

是纯右值(prvalue)

但是:

std::move(a)

得到:

xvalue(将亡值)

它有地址,但是允许被移动。


6. 一个容易混淆的地方

很多人认为:

左值就是变量,右值就是常量

这个在 C 里大致有用,但不完全正确。

例如:

inta;(a)=10;

(a)仍然是左值。

再比如:

intarr[5];arr[0]

不是变量名,但也是左值。

因为它代表一个对象。


总结:

CC++
左值有有
右值没有正式分类有严格定义
xvalue没有有
&&右值引用没有有
移动语义没有有

所以可以记:

C 里面有左值概念,但“右值体系”是 C++ 为了对象生命周期和移动语义扩展出来的。