快速搜索C ++优先级会产生许多尝试。令人不安的是,他们都是不同的。大多数人肯定是错的,尽管有些细节。
我将包括三个。第一个,来自cppreference.com声称有16个级别的优先级。 Learn.cpp有18个。 普渡大学的一个更简单的表格要简单得多。
http://en.cppreference.com/w/cpp/language/operator_precedence
http://www.learncpp.com/cpp-tutorial/31-precedence-and-associativity/
http://web.ics.purdue.edu/~cs240/misc/operators.html
这些都不是确定的,但当我查看ISO标准草案时,http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4296.pdf它甚至没有表格,说明你可以从上下文中找出它。
我的问题是1)在任何地方都有优秀的,明确的优先顺序吗?
2)任何人都可以评论这些表格所传达的所有不同“事实”吗?
例如,前两个同意后增量/减量与括号处于同一水平,这在实践中意味着什么?
(x+1)++
是没有意义的,因为x + 1是一个rexpr,显然括号表达式括号使后增量无效。
(*p)++;
我已经读过,后增量高于预增量,所以我会把它放在下面()[]等。是什么使它相等(如果是)?
cppreference声称throw与赋值运算符处于同一级别。这似乎显然是错误的,因为:
throw x += 5;
应该在投掷之前首先计算x + = 5。 learncpp不同,第三个来源根本没有提到作为运算符抛出。
这是我第一次见到运营商。我承认多年来没有研究这个标准,但回报是一个声明,为什么不扔?
任何有关优先级表位的评论都会很棒。
答案 0 :(得分:4)
优先顺序不是语言规范的一部分。它是我们人类使用的助记符设备,用于理解表达式的含义,而不像实际的解析器那样递归地分析它。
throw,?:并且C ++中的所有赋值都是语法生成赋值表达式中的替代,定义如下
assignment-expression:
conditional-expression
logical-or-expression assignment-operator initializer-clause
throw-expression
条件表达式定义为 logical-or-expression ? 表达式 :< / strong> assignment-expression , initializer-clause 是另一个赋值表达式(当它不是 braced-init-时列表), throw-expression 定义为关键字throw
,后跟可选的assignment-expression
。
从人的角度来说,我们将其描述为“相同的优先顺序,从右到左分组”。
要重复使用cppreference示例,
e = a < d ? a++ : a = d
解析为e = ((a < d) ? (a++) : (a = d))
和false ? 7 : throw 3
解析为false ? 7 : (throw 3)
,是的,您的throw x += 5
示例解析为throw (x += 5)
答案 1 :(得分:0)
看看你的三个来源,顺序基本相同--C ++参考组抛出和?:与赋值一起,它在learncpp中是独立的。普渡大学更简单,但也不那么具体。
虽然看起来有点复杂,但我建议使用learncpp作为指导,因为它是最具体的。括号规则 有点令人困惑;根据经验,使用它们就好像它们具有最高优先级一样。
关于你问题的第二部分......
(x+1)++;
肯定不会做任何事情,因为(x + 1)返回一个r值,而不能由++运算符赋值。
(*p)++;
取消引用指针p,然后递增它指向的变量。因为取消引用低于增量,没有括号,它将取消引用p然后递增指针,从而导致未定义的行为。
我认为实际写入的原因是postincrement与()相同,因此无论如何都会首先完成括号。当然,如果()计算为r值,它将返回错误。预增量较低,因为如果需要,()必须先行。举个例子,
++(*x);
在这种情况下,必须先取消引用x,然后才能递增它。
关于throw的最后一个问题,表格将其列为从右到左的评估。
的片段throw x += 5;
将评估为
throw (x += 5);
它被列为运营商,因为它显然是一种表达方式。对异常处理有更多了解的其他人可能会解释这一点。