(1)左值右值 和 (2)常见的面试题——哪些值不能做左值

参考:
博文01:https://blog.csdn.net/ZLhy_/article/details/8349300
博文02:https://blog.csdn.net/wangwei890702/article/details/20210241

一、左值和右值的定义

1、左值:

C/C++语言中可以放在赋值符号左边的变量,即具有对应的可以由用户访问的存储单元,并且能够由用户去改变其值的量。左值表示存储在计算机内存的对象,而不是常量或计算的结果。或者说左值是代表一个内存地址值,并且通过这个内存地址,就可以对内存进行读并且写(主要是能写)操作;这也就是为什么左值可以被赋值的原因了。
2、右值

相对应的还有右值:当一个符号或者常量放在操作符右边的时候,计算机就读取他们的“右值”,也就是其代表的真实值。简单来说就是,左值相当于地址值,右值相当于数据值。

个人认为左值和右值都是数据本身. 所不同的是,左值最终需要通过地址,来改变(写)数据的值. 右值通过地址或者直接是名字,或者就是个常数(可以没有地址),读取数据的值. 因此,所有左值数据都是同时是右值数据. 反之不然.
左值,右值的概念,通常常用来判断表达式,是否可以表示能够被修改的数据. 不能被修改的只能是右值. 可以被修改的是左值(同时也可以做右值用).
左值,代表数据的地址属性(寄存器,或者内存地址,甚至IOPort) 。右值:代表数据的量的属性(这个数据是什么类型的,值是多少) 但是这二者是统一的, 对于高级语言,数据,可以没有地址(比如整型常量),一定会有个值, 这个值程序员不一定,直接给出确定的值(这个数据程序中未定义).

3、++i和i++的具体实现原理

(1)// 前缀形式:即++i 的具体实现函数:
int& int::operator++() //这里返回的是一个引用形式,就是说函数返回值也可以作为一个左值使用
{//函数本身无参,意味着是在自身空间内增加1的
*this += 1; // 增加
return *this; // 取回值
}

所以对于++i的实现是:
i = i+1;
return i;

(2)//后缀形式: 即i++ 的具体实现函数:
const int int::operator++(int) //函数返回值是一个非左值型的,与前缀形式的差别所在。
{//函数带参,说明有另外的空间开辟
int oldValue = *this; // 取回值
++(*this); // 增加
return oldValue; // 返回被取回的值
}
所以对于i++的实现是:
int temp;
temp = i;
i = i+1;
return temp;

2、公司面试题实例

实例1:
int i = 0;

int *ip = &(i++); //错误

int *ip = &(++i); //正确

看到上面的语句,当时以为两个都是是对的啊,可是当我用VS2010的编译器试了试之后,才发现第一个取地址确实是错误的语句,具体的提示是:error C2102: “&”要求左值,而第二个取地址是正确的。

也就是说取地址符"&"作用的对象必须是一个左值。

看完左值的定义就不难理解为什么取地址运算符需要作用在一个左值对象上了。可为什么i++与++i有如此的区别呢?

原因是:i++不是存储在x中的值,他们的具体函数实现请看下面:

实例2:
下面哪个语句是正确的,哪个是错误的?
i++=5;
++i=5;
根据上述理论, 所以对于我们提出来的问题已经能得到解决了:
i++=5; 是错误的是因为i++返回的是编译器自动分配的临时变量temp,而这个temp并不是你程序中定义的可寻址变量的引用 ,也就是说你不能通过地址对temp进行操作.(换句话说就是不能作为左值),因为temp是一个临时变量(你没有定义,只是编译器自己加上去的。)。
++i=5;是正确的就是因为其返回值就是i;

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值