6. 优先级以及结合性
它们的作用是什么?
它们的作用是确定表达式的含义,例如:
1+2*3等价于1+(2*3)而不是(1+2)*3,这是优先级的作用。
2*3/4等价于(2*3)/4而不是2*(3/4),这是结合性的作用。
【它们不干涉求值顺序】,例如x || (y && z)的求值顺序依然是先x后(y && z),【这是||运算符本身的性质决定的】。
再比如,a = ++i中,“增加i的值”这个效果(副作用)并不一定是什么时候发生,甚至也不一定在a的值改变之前发生,也就是说,【前缀++较高的优先级不影响副作用发生的时机,它的“表达式的值是操作数自增以后的值”的含义(语义)也与i值的改变无关】。
优先级都有哪些?
由于“优先级”这个概念没有在标准中出现,所以这方面主要靠观察语法
。不幸的是C这方面并没有多么直截了当。
1. 起强制作用的括号,即(a+b)*c,而不是a()中的括号,个人认为不应放进优先级列表中(甚至,它不是一种运算符)。
2. 后缀的运算符优先级比前缀的高(个人认为,它们属于不同类型的运算符),包括“函数调用运算符”,“后缀自增运算符”,“后缀自减运算符”。【注意,++i与i++中的运算符是两种运算符。】
3. 在C语法中的postfix-expression中,不知为何混入了复合字面量(C++的更多)。当然它是要排除的。
4. unary-expression中有独特的地方:前缀++的操作数必须是一个unary-expression,而!的操作数是cast-expression,也就是说,++(int)i的合法性在语法上就被排除了。不过个人认为,把前缀++,!以及类型转换运算符放在同一个优先级并没有什么致命的危害。
5. 结合性没什么好说的。