本文转载自 : _Hebrew博客
声明:本博文用于学习总结及工作心得

在C语言中经常会遇到一个问题就是做操作数必须为左值,看一下代码:

int a=1,b=2;a<b?a:b=10;

在C++编译器环境下,能正常运行,没有错误,但是在C编译器下却会报错:

error C2106 “=”:做操作数必须为左值

什么是左值?

首先需要明白什么是表达式:

表达式由一个或多个操作数通过操作符组合而成。最简单的表达式仅包含一个字面值常量或变量。较复杂的表达式则由操作符以及一个或多个操作数构成。

什么是左值:

不严谨的说法是,左值右值的区分在于位于等号的那一侧,左侧的是左值,通常是一个变量,右侧的是右值,可以是一个变量,或者是一个表达式。

C++ 中存在两种表达式:左值可以出现在赋值语句的左边或右边。右值只能出现在赋值的右边,不能出现在赋值语句的左边。

a<b?a:b 

是一个表达式,返回的是a的值或者b的值,并不是一个变量,常数不是变量(变量:一段连续内存空间的别名),所以10不能赋值给一个常数(常数是恒定不变的,一切常数、字符和字符串都是右值),没有存储结果的空间,也就不能赋值;

将代码修改一下:

*( a < b ? &a : &b ) = 10;  

这样表达式返回的是一个(a的地址或者b的地址) 相当于*p;再通过取地址,操作地址所指向的内存空间进行间接赋值

左值在编译时可知,左值表示存储结果的地方,所以简单理解,左值就是必须有存储结果的地方,有内存空间;至于C++可以运行成功是因为C++编译器已经优化过,表达事返回的并不是a的内容(b的内容) ,而是一个变量 ;

特别是操作符重载时,进行链式编程时:

//自定义类型AAclass AA
{private :int a,b;public:AA(int a,int b){this->a = a;this->b = b;}friend void operator <<(ostream &out, AA &a1);};AA a1( 1, 2);cout << a1;cout << a1 << endl;//重载函数为:void operator <<(ostream &out, AA &a1 )
{cout<< a1.a << a1.b;return;
}

这里的做操作是cout

这时候 运行 cout << a1 ;没有错误

运行下面一句 cout << a1 << endl; 编译器报错: 左操作数必须为左值

首先 cout << a1 返回 void
而后就有 void << endl; void 不能充当做操作数,而且必须要ostream 类型的对象做参数;所以需要返回一个对象的引用(函数返回值当左值时,必须返回一个对象的应用 )

所以需要讲函数返回值修改为 ostream&

ostream& operator <<(ostream &out, AA &a1 )
{cout<< "我是cout << 重载函数" << endl;cout<< a1.a << "," << a1.b;return;
}

记得类中声明友员函数的地方,也需要修改函数返回值;修改后:

friend ostream& operator <<(ostream &out, AA &a1);

运行后返回
我是cout << 重载函数
1,2
这样就正确输出了


补充 : 左值这个名词,之前一直认为必须是个可以被赋值的的东西
也就是必须有自己的空间可以赋值,
看了这篇博文之后,也有了更加深入的理解,也是知道了右值这个东西

这里引用一句:

(常数是恒定不变的,一切常数、字符和字符串都是右值),没有存储结果的空间,也就不能赋值;

如何理解左操作数必须为左值相关推荐

  1. 左操作数必须为左值_进入“左转弯待转区”被罚怎么回事?

    想必各位老司机开车路上跑时, 一定见过这个地面标识. ▼ 考考你, 你知道地面画这个是什么意思吗? 这不就是左转待转区嘛! 每天上班必经之路的路口就有这个哎~左转车辆可以提前进入这里面等待,减少左转车 ...

  2. “函数调用的左操作数”的理解

    参考下面这个网址中两段话,对<C++ Primer>中的这句话"函数调用的左操作数"进行理解: http://www.caole.net/diary/lvalue.ht ...

  3. i++为什么不能作为左值,而++i可以作为左值

    今天看书见到如下代码: int a=2; ++a++; 根据操作符的优先级和结合性知,操作符++的优先级为3,结合性为右结合,即++a++;可以理解为++(a++); 但我把代码放在vs2015上,结 ...

  4. [转载]非常量引用的初始值必须为左值的问题

    首先,先看下面一个例子: eg.1 #include<</span>iostream> usingnamespace std; int main(){ int i =2; do ...

  5. 非常量引用的初始值必须为左值

    问题描述 先看一段报错的代码: #include<iostream> using namespace std;int main() {int i = 2;double &r = i ...

  6. 如何理解CNN中的权值共享

    记录一下深度学习中CNN中的权值共享 首先,卷积网络的核心思想是将:局部感受野.权值共享(或者权值复制)以及时间或空间亚采样这三种结构思想结合起来获得了某种程度的位移.尺度.形变不变性. 通俗理解,所 ...

  7. python使用matplotlib2D绘图库的折线图绘制小案例(方便matplotlib的学习理解)——随机数做幸运值,绘制一周的幸运趋势

    python使用matplotlib2D绘图库的折线图绘制小案例(方便matplotlib的学习理解)--随机数做幸运值,绘制一周的幸运趋势 QQ:3020889729 小蔡 小案例内容简介 实例 第 ...

  8. 非常量引用的初始值必须为左值解决方式

    看下面的这个函数与调用,这个时候就会出现非常量引用的初始值必须为左值解决方式的错误 修改方法:函数声明的时候,加一个constPoint3f getWorldPoints(const Point2f& ...

  9. 函数的返回竟然能作为左值

    函数返回尽然能作为左值     函数参数里的二级指针  函数参数里的(数据类型引用) 经典不是优雅 #include <iostream> #include <iomanip> ...

最新文章

  1. PHP:第五章——字符串的概念
  2. Mac 使用SSH远程登录
  3. flash 游戏 ui 制作方案
  4. 猴子选大王c语言课程设计,【C/C++】猴子选大王
  5. python打开.data_DataX初体验-python命令启动以及纯java启动
  6. 1018. 可被 5 整除的二进制前缀
  7. 远程登录出现 身份验证错误 要求的函数不受支持
  8. 初识Jasima-调度仿真系列教程预告
  9. Spring时间(Date)类型转换+自定义
  10. 喜乐美容美发管理系统 v20070625 加强版 下载
  11. 硬件设计——串联直流稳压电源
  12. 算术-几何平均值不等式的常见证明
  13. 移动智能终端PIN码破解
  14. 搜索竞价推广方式OCPC VS CPC,谁更强
  15. 为什么微信付款服务器异常,微信付款怎么老是交易异常怎么回事?可能是这些原因...
  16. Intel IoT Roadshow 北京站活动感想
  17. 图像合成:Multi-scale Image Harmonization
  18. python 矩阵化为最简阶梯型
  19. 【SV中local::的用法】
  20. 研发管理01:项目管理(PM) 与 Scrum Master (SM)

热门文章

  1. Java黑皮书课后题第8章:*8.21(中心城市)给定一组城市,中心城市是和其它所有城市具有最短距离的城市。编写一个程序,提示用户输入城市数目以及位置(坐标),找到中心城市以及与其他城市总距离
  2. Java黑皮书课后题第5章:*5.14(计算最大公约数)下面是求两个整数n1和n2的最大公约数的程序清单5-9的另一种解法:...提示用户输入两个正整数,然后显示最大公约数
  3. 我的世界进服务器显示C1.8-1.11,【插件】 LibsDisguises —— 让你的玩家变成生物或者其他 [1.8-1.11]...
  4. STL源码剖析---vector
  5. 开关和灯泡的对应关系
  6. 关于Linux的修复(重新引导)
  7. 视觉编码(Visual Encoding)
  8. P4332 [SHOI2014]三叉神经树(LCT)
  9. Lintcode---统计比给定整数小的数的个数
  10. 多态部分作业 3..创建Rodent(啮齿动物):Mnouse(老鼠),Gerbil(鼹鼠),Hamster(大颊鼠)