1、什么是左值和右值?
左值就是出现在表达式左边的值(等号左边),可以被改变,他是存储数据值的那块内存的地址,也称为变量的地址;
右值是指存储在某内存地址中的数据,也称为变量的数据。
左值可以作为右值,但右值不可以是左值。
因此也只有左值才能被取地址。
2、举两个问题:
int i = 0;
(i++)+=i; //错误
(++i)+=i; //正确
int *ip = &(i++); //错误
int *ip = &(++i); //正确
3、为什么i++不能作左值?
我们来看i++和i++的实现就明白了。
1
2
3
4
5
6
|
// 前缀形式:
int
&
int
::operator++()
//这里返回的是一个引用形式,就是说函数返回值也可以作为一个左值使用
{
//函数本身无参,意味着是在自身空间内增加1的
*
this
+= 1;
// 增加
return
*
this
;
// 取回值
}
|
1
2
3
4
5
6
7
|
//后缀形式:
const
int
int
::operator++(
int
)
//函数返回值是一个非左值型的,与前缀形式的差别所在。
{
//函数带参,说明有另外的空间开辟
int
oldValue = *
this
;
// 取回值
++(*
this
);
// 增加
return
oldValue;
// 返回被取回的值,临时变量
}
|
简单得到理解,就是i++返回的是一个临时变量,函数返回后不能被寻址得到,它只是一个数据值,而非地址,因此不能作为左值。
更简单的代码解释:
1
2
3
4
5
6
7
8
9
10
11
12
13
|
// i++:
{
int
tmp;
tmp=i;
i=i+1;
return
tmp;
}
// ++i:
{
i=i+1;
return
i;
}
|