算下来已经很久以前了,大概有那么几个星期了吧。看到了帖子上有人问为什么下面的语句的对错原因
int i = 0;
int *ip = &(i++); //错误
int *ip = &(++i); //正确
看到上面的语句,当时以为两个都是是对的啊,可是当我用VS2010的编译器试了试之后,才发现第一个取地址确实是错误的语句,具体的提示是:error C2102: “&”要求左值,而第二个取地址是正确的。
也就是说取地址符"&"作用的对象必须是一个左值,左值的概念是什么呢?看一下百度对于C/C++中左值的定义:
左值:
C/C++语言中可以放在赋值符号左边的变量,即具有对应的可以由用户访问的存储单元,并且能够由用户去改变其值的量。左值表示存储在计算机内存的对象,而不是常量或计算的结果。或者说左值是代表一个内存地址值,并且通过这个内存地址,就可以对内存进行读并且写(主要是能写)操作;这也就是为什么左值可以被赋值的原因了。相对应的还有右值:当一个符号或者常量放在操作符右边的时候,计算机就读取他们的“右值”,也就是其代表的真实值。简单来说就是,左值相当于地址值,右值相当于数据值
看完左值的定义就不难理解为什么取地址运算符需要作用在一个左值对象上了。可为什么i++与++i有如此的区别呢?
原因是:i++不是存储在x中的值,他们的具体函数实现请看下面:
int& int::operator++() //这里返回的是一个引用形式,就是说函数返回值也可以作为一个左值使用
{//函数本身无参,意味着是在自身空间内增加1的
*this += 1; // 增加
return *this; // 取回值
}
const int int::operator++(int) //函数返回值是一个非左值型的,与前缀形式的差别所在。
{//函数带参,说明有另外的空间开辟
int oldValue = *this; // 取回值
++(*this); // 增加
return oldValue; // 返回被取回的值
}
错误的是因为i++返回的是编译器自动分配的临时变量temp,而这个temp并不是你程序中定义的可寻址变量的引用 ,也就是说你不能通
过地址对它进行操作.(换句话说就是不能作为左值)。++i=5;是正确的就是因为其返回值就是i;