C语言的优先性和结合方向

来源:岁月联盟 编辑:zhu 时间:2009-02-13
问题

C语言的书籍的附录都要说一个问题,就是优先性和结合方向。
我的理解是这些是建立在表达式的基础之上的,写一个c语言的表达式或者看一个C语言的表达式,先看优先性,在优先性相同的情况下,再根据结合方向,判断表达式的那个部分先运算,那个后运算。如:
1. a=b=c=0,只有一个=,因此优先性相同,因此看结合方向,结合方向是从右到左,因此,整个表达是从右开始计算,上面等价与a=(b=(c=0)),这是正确地,但是下面这个问题该怎么解释哪?
2. a=*p++;
=,优先级低于*,++,也就是等价于a=(*p++);但是*p++,这个部分是怎么运算哪?写过C的都知道*先,++后,可是在C语言附录中,*(取地址),++是同优先级的,2级,结合方向是从右到左,按照这个理解就应该*(p++),这才是从右到左吧,不知道理解有没有问题,但是这个和实际应用的相反的嘛?


解答:

关于a = *p++;
首先,“后自增”运算符的优先级是高于“*”的,“前自增”才跟“*”平级。这一点楼主没有看仔细。
然后,为什么优先级高于“*”,结果还是取出了原来的指针指向的内容呢?

有很多书上说“后自增”是先“用”值,再加1,这种说法是很不严格很不确切的。正是这种不严格和不确切,才导致了许多初学者在*p++上绊倒。
再看一个更简单的例子:
int i = 10;
int j = i++;
现在j等于多少?大家都知道是10,问原因,很多人都会说是“在后自增的情况下,是先赋值再加1”。这中说法完全不负责任,赋值运算赋“=”的优先级比“后自增”低好几个级别,怎么可能发生“先赋值”这样的事?

正确的语义解释是:“前自增”和“后自增”都是先将变量加1,然后区别在于加1后返回值,后自增在加1后返回的是原来的,而前自增返回的是加1后新值。
从效果上,i++相当于一个逗号表达式:“tmp = i, ++i, tmp”

图片内容