很多变成语言都没有所谓"左值右值"一说,为什么C++有这个说法?

sadsaer 2015-01-05 12:54:11
如题,为什么C+要区分一大堆左值/右值相关的内容呢?
...全文
265 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
真相重于对错 2021-07-23
  • 打赏
  • 举报
回复

[右值
右值表达式包括纯右值、亡值。

性质:

右值不能由内建的取址运算符取地址:&int()、&i++[3]、&42 及 &std::move(x) 是非法的。
右值不能用作内建赋值运算符及内建复合赋值运算符的左操作数。
右值可以用于初始化 const 左值引用,这种情况下该右值所标识的对象的生存期被延长到该引用的作用域结尾。
右值可以用于初始化右值引用,这种情况下该右值所标识的对象的生存期被延长到该引用的作用域结尾。
当被用作函数实参且该函数有两种重载可用,其中之一接受右值引用的形参而另一个接受 const 的左值引用的形参时,右值将被绑定到右值引用的重载之上(从而,当复制与移动构造函数均可用时,以右值实参将调用其移动构造函数,复制和移动赋值运算符与此类似)](https://zh.cppreference.com/w/cpp/language/value_category#.E5.8F.B3.E5.80.BC)

真相重于对错 2021-07-23
  • 打赏
  • 举报
回复

别的语言也应该有左右值之分,可能只是没有明确说明而已
例如
你可以写
c=a+b
但你不能写
a+b=c

真相重于对错 2021-07-23
  • 打赏
  • 举报
回复

img

赵4老师 2015-01-05
  • 打赏
  • 举报
回复
《深度探索C++对象模型》 《C++反汇编与逆向分析技术揭秘》 做个可能不太恰当的比喻: 人想让狗帮忙逮只兔子,可是人说话狗听不懂,于是人发明了一种介乎人言和狗语之间的语言,即口令。 人想让电脑帮忙做计算,可是人话电脑听不懂,于是人发明了一种介乎人言和汇编机器码之间的语言,即C语言。 人对狗的口令得让人容易学、也得让狗容易懂。 C语言同样得让人容易学、也得让电脑容易懂。 相比之下C++、Java就是人学得费劲、电脑也经常闹不懂。
赵4老师 2015-01-05
  • 打赏
  • 举报
回复
世上本无事,庸人自扰之。
pengzhixi 2015-01-05
  • 打赏
  • 举报
回复
引用 12 楼 sadsaer 的回复:
[quote=引用 11 楼 pengzhixi 的回复:] [quote=引用 9 楼 sadsaer 的回复:] [quote=引用 6 楼 lin5161678 的回复:] [quote=引用 5 楼 sadsaer 的回复:] [quote=引用 3 楼 a30037338 的回复:] c也有啊, 不止c++, 左值和右值的一个最根本的区别是 左值可以使用&符号, 右值是不可以的 , 记住这一条足矣, 至于为什么要有, 你去问 丹尼斯.里奇 或者 本贾尼
这个说法不对啊,右值也可以取地址的,像我下面的这个程序:

class M{};
void f(M*){}
int main()
{
    f(&M());
    return 0;
}
[/quote]为什么你会觉得 M()是一个右值? [/quote] 因为M()没有名字,所以我认为是一个右值 [/quote] M()是一个临时对象也是一个右值,不应该这么使用[/quote] 同意,M()是一个右值,但是可以取地址,虽然不应该这样用。 所以不能说右值不能取地址。 [/quote]准确的说不应该对右值对象进行取址操作,首先右值对象确实是有存储空间的,但是这个空间是在内存还是寄存器你是不确定的,如果在寄存器你是不可能取地址的,即使在内存像这种临时对象的生命周期是有限的,就算取到地址也许那段内存里面的东西由于对象被销毁而变得无效
真相重于对错 2021-07-23
  • 举报
回复
@pengzhixi 你这段代码是错误的
sadsaer 2015-01-05
  • 打赏
  • 举报
回复
引用 11 楼 pengzhixi 的回复:
[quote=引用 9 楼 sadsaer 的回复:] [quote=引用 6 楼 lin5161678 的回复:] [quote=引用 5 楼 sadsaer 的回复:] [quote=引用 3 楼 a30037338 的回复:] c也有啊, 不止c++, 左值和右值的一个最根本的区别是 左值可以使用&符号, 右值是不可以的 , 记住这一条足矣, 至于为什么要有, 你去问 丹尼斯.里奇 或者 本贾尼
这个说法不对啊,右值也可以取地址的,像我下面的这个程序:

class M{};
void f(M*){}
int main()
{
    f(&M());
    return 0;
}
[/quote]为什么你会觉得 M()是一个右值? [/quote] 因为M()没有名字,所以我认为是一个右值 [/quote] M()是一个临时对象也是一个右值,不应该这么使用[/quote] 同意,M()是一个右值,但是可以取地址,虽然不应该这样用。 所以不能说右值不能取地址。
pengzhixi 2015-01-05
  • 打赏
  • 举报
回复
引用 9 楼 sadsaer 的回复:
[quote=引用 6 楼 lin5161678 的回复:] [quote=引用 5 楼 sadsaer 的回复:] [quote=引用 3 楼 a30037338 的回复:] c也有啊, 不止c++, 左值和右值的一个最根本的区别是 左值可以使用&符号, 右值是不可以的 , 记住这一条足矣, 至于为什么要有, 你去问 丹尼斯.里奇 或者 本贾尼
这个说法不对啊,右值也可以取地址的,像我下面的这个程序:

class M{};
void f(M*){}
int main()
{
    f(&M());
    return 0;
}
[/quote]为什么你会觉得 M()是一个右值? [/quote] 因为M()没有名字,所以我认为是一个右值 [/quote] M()是一个临时对象也是一个右值,不应该这么使用
lin5161678 2015-01-05
  • 打赏
  • 举报
回复
引用 9 楼 sadsaer 的回复:
因为M()没有名字,所以我认为是一个右值
是不是左值 和 有没有名字毫无关系 这里是 M() 会指定一个M类对象 是一个左值
sadsaer 2015-01-05
  • 打赏
  • 举报
回复
引用 6 楼 lin5161678 的回复:
[quote=引用 5 楼 sadsaer 的回复:] [quote=引用 3 楼 a30037338 的回复:] c也有啊, 不止c++, 左值和右值的一个最根本的区别是 左值可以使用&符号, 右值是不可以的 , 记住这一条足矣, 至于为什么要有, 你去问 丹尼斯.里奇 或者 本贾尼
这个说法不对啊,右值也可以取地址的,像我下面的这个程序:

class M{};
void f(M*){}
int main()
{
    f(&M());
    return 0;
}
[/quote]为什么你会觉得 M()是一个右值? [/quote] 因为M()没有名字,所以我认为是一个右值
  • 打赏
  • 举报
回复
提供左右值其实是为了编程方便,提高类实例的操作性能,同时也对编译器的优化有帮助。
unituniverse2 2015-01-05
  • 打赏
  • 举报
回复
C++/C和当前其他主流语言相比更重视性能(或者说这门语言的设计者假定你选用它的原因是把性能当做工程的一个关键指标,而对其他语言来说,性能只是一个可选优化的特征) C++和C相比,因为C中的左右值不像C++那样会直接影响设计,因此也显得似乎没那么重要。C的右值特性主要应用点只是在于防错、检错,而C++(主要从C++11开始)则直接关系到重载的具体行为了
lin5161678 2015-01-05
  • 打赏
  • 举报
回复
引用 5 楼 sadsaer 的回复:
[quote=引用 3 楼 a30037338 的回复:] c也有啊, 不止c++, 左值和右值的一个最根本的区别是 左值可以使用&符号, 右值是不可以的 , 记住这一条足矣, 至于为什么要有, 你去问 丹尼斯.里奇 或者 本贾尼
这个说法不对啊,右值也可以取地址的,像我下面的这个程序:

class M{};
void f(M*){}
int main()
{
    f(&M());
    return 0;
}
[/quote]为什么你会觉得 M()是一个右值?
sadsaer 2015-01-05
  • 打赏
  • 举报
回复
引用 3 楼 a30037338 的回复:
c也有啊, 不止c++, 左值和右值的一个最根本的区别是 左值可以使用&符号, 右值是不可以的 , 记住这一条足矣, 至于为什么要有, 你去问 丹尼斯.里奇 或者 本贾尼
这个说法不对啊,右值也可以取地址的,像我下面的这个程序:

class M{};
void f(M*){}
int main()
{
    f(&M());
    return 0;
}
真相重于对错 2021-07-23
  • 举报
回复
@sadsaer 你这段代码是错误的,如果能通过,说明编译器不符合c++标准
赵4老师 2015-01-05
  • 打赏
  • 举报
回复
电脑内存或文件内容只是一个一维二进制字节数组及其对应的二进制地址; 人脑才将电脑内存或文件内容中的这个一维二进制字节数组及其对应的二进制地址的某些部分看成是整数、有符号数/无符号数、浮点数、复数、英文字母、阿拉伯数字、中文/韩文/法文……字符/字符串、汇编指令、函数、函数参数、堆、栈、数组、指针、数组指针、指针数组、数组的数组、指针的指针、二维数组、字符点阵、字符笔画的坐标、黑白二值图片、灰度图片、彩色图片、录音、视频、指纹信息、身份证信息……
此后三年 2015-01-05
  • 打赏
  • 举报
回复
c也有啊, 不止c++, 左值和右值的一个最根本的区别是 左值可以使用&符号, 右值是不可以的 , 记住这一条足矣, 至于为什么要有, 你去问 丹尼斯.里奇 或者 本贾尼
还很菜的猴子 2021-07-22
  • 举报
回复
@此后三年 C++11右值也可以取地址了
真相重于对错 2021-07-23
  • 举报
回复
@还很菜的猴子 在c++中能取址就不是右值

65,211

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧