在运算符重载javascript:void(0)一文中,我提到了运算符的2个性质:
优先级和结合性。
结论:
决定运算符的运算顺序,需要且只需要2个规则,一个是优先级,一个是结合性,
所以优先级相同的运算符,要么全是左结合性,要么全是右结合性。
实际上,C和C++中,优先级分为十几级,右结合性只有其中的三个等级,即三类运算符:单目运算符、三目运算符、赋值运算符。
然而,如何理解a---b?是a - --b还是a-- - b?
这里就涉及到编译原理中的分词原则,分词是从左往右最长匹配的贪心原则,
根据贪心原则,a--b就是a-- b,是无法编译的,无法理解为a - -b,因为先分词后才能按照高级语言的语法来编译。
而a---b就是a-- - b
有了这个原则,表达式想表达的意思就没有歧义了。
比如---b这个表达式,就是-- -b,这也是无法编译的。
然而,--的优先级比-高,但是a-- -b是先计算a-b,再计算a--,这怎么理解呢?
我的理解是,运算符的优先级和结合性,其实是规定了如何添加括号,而无论如何添加括号,后置++和--依旧是在表达式计算完成之后才能计算。
PS:除了C++中的作用域解析运算符::之外,括号()的优先级是最高的。
顺带一提,a--+-+-b这个表达式如何理解?
答案是a-- + - + -b
加减号放在变量之前,也可以表示正负号,不难发现,这2个不需要什么规则做明显的区分,这个是没有歧义的。
和数学是一致是,3-5可以理解为3和-5这2个数的和,因为负数的定义就是如此,而且数学中也有3- -5和3- +5这种表达,是完全一致的,无论是数学还是C/C++中,这个都是没有歧义的。