如何理解左操作数必须为左值

本文转载自 : _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的内容) ,而是一个变量 ;

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

//自定义类型AA

class 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
这样就正确输出了


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

这里引用一句:

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值