在理解指针表达式之前先有一个概念就是“左值”和“右值”,对于左值就是可以出现在赋值符号左边的东西,右值就是那些可以出现在赋值符号右边的东西。进一步抽象可以这样理解:左值应该可以作为一个地址空间用来存放一个值,而右值可以作为一个值来处理,当然需要说明的是有些是既可以作为左值也可以作为右值的,例如:定义a为一个指针指向b,那么*a既可以作为一个右值即地址b中存放的数据,也可以作为一个左值即表示b的地址。其实说到这里就已经说明了一个简单的指针表达式了,那就是:*a。下边就再讨论一些其他的指针表达式。
首先做一个声明:
char ch = “a”;
char *cp = &ch;
其实这个声明很明了,这个声明声明了两个变量:ch和cp,cp作为一个指针指向ch。为了便于随后的说明,我现在做如下设想:cp变量地址为0x12,ch变量的地址为0x23,即现在空间cp中的内容为:0x23,ch中的内容为a字符。下边做一些表达式的分析:
1、&ch:右值:表示ch的地址信息,即0x23这个值。左值:它作为左值是非法的,因为它已经不可以作为一个空间来使用。
2、cp:右值;表示cp中的内容,即ch的地址信息(0x23)。左值:表示cp这个地址空间,作为一个空间使用。
3、&cp:右值:表示cp的地址信息,即0x12这个数据。左值:类比&ch也可知它作为左值是非法的。
4、*cp:这个和我们博文开始的例子是一样的。右值:表示ch内的内容(a字符)。左值:表示ch这个地址空间。
5、*cp + 1:要注意*(我个人理解为间接范围操作符)的优先级高于+。右值:运算过程为:首先做间接的访问操作得到a字符的一个拷贝,再加1,得到字符b。左值:位置未清晰定义,是非法的。
6、*(cp + 1):这个表达式可以把cp+1看做一个整体,它作为指针加法运算的结果是一个右值,表示ch的下一个地址,*(cp+1)做右值表示对ch下一个地址中的数据内容,做左值表示ch下一个地址这个空间(注意:cp+1本身不是左值)。
7、++cp与cp++:该表达式涉及++运算符,两个表达式除了都有cp+1的功能外,两个表达式整体的结果也都会得到变量的拷贝,但是前缀++会先执行加1的操作再获得变量拷贝,而后缀++则是先进行变量的拷贝再执行加1操作。因此++cp表达式作为右值执行后cp和++cp都会指向cp后面的内存位置,而cp++作为右值执行后cp会指向cp内存后面的内存位置,而cp++整体则是指向cp原来的内存位置(0x12)。他们都没有清晰的位置定义,所以都是不合法的左值。
8、*++cp与*cp++:对比上边两个表达式这两个理解起来也很容易了,只是进行了一次指针运算即间接访问操作,对于右值来看,这两个表达式结果只是对上边两个操作结果的间接访问,即对应空间内的数据;对于左值来看,这回就是合法的了,对应的就是响应地址的地址信息了。
综合:其实关于指针的表达式还有很多,不同运算符之间的相应组合都会形成相应操作符,只要根据相应的运算符的优先级一步步运算都可以得到其相应结果。叙述了这么多的表达式,但是在实际运用中大多数还是一般的表达式,之所以把他们都整理一下是因为:1、有助于我们去理解别人的代码,因为别人很可能会写出这些表达式。2、有个别时候是用得到的,学习也是有必要的。3、总结这么多最终目的并不是要简单的去理解现有的表达式,而是通过现有的表达式的整理和理解,充分理解指针以及指针表达式的真正含义,深入的理解指针这个东西,有助于后期的学习和提高。