为了理解有些操作符存在的限制,必须理解左值与右值之间的区别。
通俗的说:左值是出现在赋值号左边的东西,右值是出现在赋值号右边的东西。
比如说:a=b+4;
a是左值,因为它有一定的存储空间;b+4是右值,因为它指定了一个值。
但是他们可以互换吗?即b+4=a;原先用作左值的a可以当做右值,但是b+4不可用 当做左值,因为它并未标识一个特定的位置。因此,此条赋值语句是错误的。
注意当计算机计算b+4时,它的结果必然保存于机器的某个地方,但程序员必并没有办法预测该结果会储存在什么地方,也没法保证这个表达式的值下次还会储存在那个地方,其结果是,这个表达式不是一个左值。基于同样的理由,字面值常量也都不是左值。
但并不意味表达式和常量不可以做左值,变量可以做左值。在下面的赋值语句中,左值便是一个表达式。
int a[30];
....
a[b+10]=0;
下标引用是操作符,(前面博客有详细介绍),所以表达式的左边实际是个表达式,但它确是一个合法的左值,因为它标识了一个特定的位置,我们以后可以在程序中引用它。请看另一个例子:
int a, *p;
p=&a;
*p=20;
请看第二条赋值语句,它左边的那个值显然是个表达式,但是个合法的左值。为什么?指针p的值是内存中某个特定位置的地址,*操作符使机器指向那个位置。当它做左值使用时,这个表达式指定需要进行修改的位置。当它作为右值时,它就提取当前存储于这个位置的值。
另外,c语言中的前置++和后置++,都不可以做左值。
对左值和右值有了一定了解后,我们一起来做些习题:
char ch='a';
char *cp=&ch;
1.&ch; //&ch是地址常量,不能做左值,可以做右值
2.cp; //cp是指针变量,也是变量,可以做左值和右值
3.&cp ; //&cp是地址常量,不能做左值,可以做右值
4.*cp+1; //*cp+1表达式的结果是常量,不能做左值,可以做右值,参照上面b+4
5. *(cp+1); //*(cp+1)表示ch之后一段空间,可以做左值和右值
6. ++cp ; //c语言中变量的前置++不能做左值,可以做右值
7. cp++; //c语言中变量的后置++不能做左值,可以做右值
8. *++cp; //*++cp是ch的下一段空间,可以做左值和右值
9.*cp++; //++优先级高,可以做左值和右值
10.++*cp; //不能做左值,可以做右值
11.(*cp)++; //不能做左值,可以做右值
12. ++*++cp; //表达式是对ch下一空间内容的前置++,不能做左值,可以做右值
13.++*cp++; //++*(cp++),不能做左值,可以做右值
注:本篇博客前半部分参照《C和指针》
如有不足之处,请各位大神多多提点,谢谢支持。