左值(lvalue)和右值(rvalue)最先来源于编译。在C语言中表示位于赋值运算符两侧的两个值,左边的就叫左值,右边的就叫右值。
定义:
左值指的是如果一个表达式可以引用到某一个对象,并且这个对象是一块内存空间且可以被检查和存储,那么这个表达式就可以作为一个左值。
右值指的是引用了一个存储在某个内存地址里的数据。
从上面的两个定义可以看出,左值其实要引用一个对象,而一个对象在我们的程序中又肯定有一个名字或者可以通过一个名字访问到,所以左值又可以归纳为:左值表示程序中必须有一个特定的名字引用到这个值。而右值引用的是地址里的内容,所以右值又可以归纳为:右值表示程序中没有一个特定的名字引用到这个值。
++a的话因为返回结果和运算之后的a一样,所以++a返回的是真实的a,可以被重新赋值,所以可以作为左值。而a++返回的是运算之前的a,而此时a已经+1了,返回的数据其实是过去的a,它是另外复制出来的,而不是真正的a,所以无法被赋值,所以它只能是右值。
所以a++;在执行当中的顺序是,先把a的值复制出来,进行整体运算,然后再a=a+1。
错误了吧,在a自增1的同时,已经把a+1的值赋值给a。不然怎么会存在
a=1
b=a++
执行后就是
b=1
a=2
这就奇怪了,既然“在a自增1的同时,已经把a+1的值赋值给a”,那为什么b还是1?b=a++这表达式的实质是b=a;a=a+1;。b=a++这种写法只对b=a;a=a+1;的简化而已。就是说当a赋给b时a还没有加1,赋值运算后a才执行++运算。正因为这个原因才有:a是左值,而a++不是左值!由于C规定:后++在前面的变量参与运算时++是无效的,只前面的变量参与运算完成后++才生效!
不是这样的,++a才是先把a的值加1,然后返回a
a++是先返回a的值,然后把a的值加1
所以说a++是需要用一个临时变量保存a的原值,a自增1,然后返回临时变量,这几乎是唯一的使a自增1并返回原值的办法……如果返回a本身的话,因为被返回的a和自增的a是同一个变量,因此被返回的a在a++这一个单独的运算完成之后,其他运算利用a++的返回值之前,一定是已经增加1了的,也就是说++a可以返回左值,即a自身,但a++不可以……
追问临时变量有没有分配存储空间,返回之后,临时变量还存在吗,还有一个问题,谭浩强的书上书说a++是a参与运算后,然后a的值再自增1,理解为就是将a++分两步进行,先返回a,然后自增,与你的说法矛盾,但从产生临时变量这一角度理解,感觉更为容易一些,所以请问你从哪儿看到的关于产生临时变量这一说法,谢谢
大概理解了,但是对于你提到的 “同步”和“对象”是什么意思呢
追答对象,就是在存储区里有确切存在的内存存储它的值,以后我还能够调用它,并取得它的值。
不同步,a++这个表达式的值,与a的值不同了 如果a=10,那么a++的值是10,而a已经是11了
关于下面那位仁兄说的 产生临时变量的说法,你怎么看?
追答谭浩强的书上说的是让你便于理解的啦。那位仁兄说的是对的啦。
a++可以这么理解,它相当于一个函数
int m(int * k)
{
int y=*k;
*k=*k+1;
return y;
}
这样a++的表达式的值是a之前的值,而a也已经加1了。
临时变量会产生的,但在a++所在的表达式结束就销毁了,不存在了,它会被分在内存的,但不能引用,因为他会被很快地销毁掉。
对于++a而言,返回值所对应的变量是a,a所对应的是分配给a的内存区域里的值,是这样的吧;
那a++呢,如果他是先产生临时变量记录a的值,表达式结束后,临时变量就被销毁了,(问1)怎样映射出a的值并将其反回呢?就算返回成功了,那么此时临时变量已经被销毁,(问2)返回值所对应的又是什么呢(对于++a而言,返回值所对应的变量是a。。。。)? 求解答
你理解的都对
问1:对于a++,你如果学过c++就知道,它其实内部有一个函数调用的,那个函数的作用与这个函数作用一样
int m(int * k)
{
int y=*k;
*k=*k+1;
return y;
}
临时变量是在它所在的整个表达式结束后就结束了如:
a++;
这句执行后,我们就无法取得a++表达式的值了啦
b=a++;
而这句是赋值表达式,a++是整个表达式的子表达式,它的临时变量在赋值表达式结束后销毁,所以b可以取得a++表达式的值。
问2:
返回值对应的就是那个临时变量啦,而这个临时变量,我们只能用它的值,而不能用它的对象,因为它会很快销毁
不是这样的,a++是先返回a的值,然后把a的值加1
例如
a=1
b=a++
执行后就是
b=1
a=2
对,是我搞错了。