概述
这到底是一个什么样的问题呢?如果不深究,大家好像并不会太在意,而且很多人在编写代码的时候不会出现这样的概念,也不大会出错。但是我还是想探究一下。比如:
int a;
int b;
1) a = 5;
2) b = a + 1;//这句话是对的
而3) a + 1 = 10;//这句话就是错的呢?
关于左值右值的要点:
1) 变量可以作为左值也可以作为右值
有人会说,3)中的变量a不是可以作为左值吗?为什么是错的。看看第二点。
2) 在进行表达式求值时,请注意每个操作符需要的操作数是左值还是右值,且操作符的操作结果是左值还是右值
什么意思?a + 1 = 10中,等号左边a+1是个表达式,其操作是加法,标准规定:加法操作的两个操作数都要是右值,也就是说a其实取的是右值,而不是左值。2)句中的
a也是右值。1)句中a才是左值。那么左值和右值到底有什么不同呢?
3) 左值是位置(地址),右值是一个值(位置里面的内容)
以1)句为例,因为a在等号左边单独出现,没有参与任何的操作符,所以它是个左值,因为是左值,它表示的是一个位置,即a的地址,a=5,就是将值5放进a的地址。
再看看3),a虽然也在等号的左边,但不能仅仅因为a出现在等号的哪一边而确定它是左值还是右值,在3)中a参与了加号操作符,而加号操作符需要的两个操作数都是右值,
所以a就算是出现在等号左边,它取的也是右值,即a的内容5, 那么a + 1 = 10是错的就显而易见了。再看2), a参与了加号操作,取的是右值,为5,b则是左值,是位置,
所以2)的意思是将6存入b这个位置作为内容。
4)在使用右值的地方可以使用左值,但在需要左值的地方不能使用右值
3)句除了上面说的出错的原因外,还有这个要点的原因。怎么理解? a+1是一个加法操作,其结果是一个右值。右值是不能出现在等号左边作为左值的。所以3)句出错的
原因其实有两点。
那如何理解左值可以用在使用右值的地方呢?
看看例子
int c = 5;
int *p = &c;
int d;
4) d = *p + 1;
5) *p = 9;
看到4)和5)的特点吗?*p既出现在了等号的左边,也出现在了等号的右边。根据规定:间接访问操作符*的操作数是右值,而操作的结果是左值,也就是说*p这个表达式
的结果其实是左值,但它出现在了等号两边,而且都没有错。那么如何理解4)和5)呢?
先看4), 因为*操作符的操作数是右值,所以p取的是右值,即内容,也就是c的地址,来看看*p,有人会说既然p取的是内容,也就是c的地址,那*p是不是就是取的c这个
地址里面的内容5呢?不是的。我们可以把*p想象成,从p里面抛出了一个箭头,直指向c这个地址,注意*p的结果是个左值,左值是位置,即c的地址,但是在4)中*p的结果 参与了加法操作,所以它又神奇的变成了右值,既然是右值,那当然是c这个地址的内容5了。
那么5)句呢?p作为*操作符的操作数,取的是右值,即c的地址,*p操作抛出箭头,指向c,其结果是左值,左值是位置,即c的地址,所以将9存入c这个位置。
说了这么多,感觉有点乱啊,不知道大家看明白没?
再来看看下面的例子:
int a = 2;
int *p = &a;
int b;
6) *p + 1 = 12; //错的
尽管*p的结果是左值,加法操作数需要右值,但是左值可以出现在使用右值的地方,这没有错,但加法操作的结果是右值,而等号左边只能是左值,所以错了。
7) b = *(p + 1);
这句话在语法上没错,但运行中可能出错。因为p参与了加法操作,所以取右值,即a 的地址,然后改地址加1(注意因为a是整型,所以此处加1其实加的是4个字节), 也就
是指向了a后面的地址,然后进行*操作,即向a后面的那个地址抛出箭头,其结果是一个左值,又因为左值可以出现在使用右值的地方,神奇变成右值,所以*(p+1)的结果
是去a后面的地址的内容,但该内容未知,因此语法是没错,运行时可能出错。
8) *(p + 1) = 12;
同样是语法没错,运行时可能非法,因为它修改了a后面的地址的内容,这是非法修改,可能引发打错。
最后
以上就是无心绿草为你收集整理的左值与右值的全部内容,希望文章能够帮你解决左值与右值所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复