【发布时间】:2012-11-11 00:18:41
【问题描述】:
我查阅过的几乎所有 C/C++ 运算符优先级表都将三元条件运算符列为比赋值运算符具有更高的优先级。然而,有几个表,例如wikipedia 上的一个和operator-precedence.com 上的一个,将它们置于相同的优先级。它是哪个,更高还是相同?
【问题讨论】:
标签: c++ c ternary-operator operator-precedence
我查阅过的几乎所有 C/C++ 运算符优先级表都将三元条件运算符列为比赋值运算符具有更高的优先级。然而,有几个表,例如wikipedia 上的一个和operator-precedence.com 上的一个,将它们置于相同的优先级。它是哪个,更高还是相同?
【问题讨论】:
标签: c++ c ternary-operator operator-precedence
在 C++ 语法中,
赋值表达式: 条件表达式 逻辑或表达式赋值运算符初始化子句 抛出表达式 条件表达式: 逻辑或表达式 逻辑或表达式?表达式:赋值表达式 初始化子句: 赋值表达式 支撑初始化列表可以合并为
赋值表达式: 逻辑或表达式 逻辑或表达式?表达式:赋值表达式 逻辑或表达式赋值运算符赋值表达式 逻辑或表达式赋值运算符初始化子句 抛出表达式如果只看= 和?:,如果忽略? 和: 之间的内部表达式,这显然会赋予?: 和= 完全相同的优先级。
这与 C 语法不同,在 C 语法中,?: 的左操作数和右操作数都不能将赋值运算符作为其最顶层的运算符。
所以对于 C,给它们不同的优先级是有意义的。
也就是说,优先级只是标准实际所说的近似值,您选择的任何优先级都会显示这些级别具有误导性或完全错误。根据你的解释,?: 的内在表达可能是其中之一,它是给我的。
【讨论】:
a = b ? c : d 中,b ? c : d 是包含赋值表达式的子表达式,但都没有用括号指定。
a ? b : c = d,但我在回答中避免了这一点:)
a ? b = c : d 中加上括号,所以第二个例子没用。第一个示例只是表明? 的优先级高于(或相同)=。
C++ 的答案是?: 和= 具有相同的优先级。是的,几乎所有的 C++ 运算符优先级表都是错误的。
在 C 中,?: 是否高于 = 并不重要,因为在 C 中,?: 运算符不允许计算为左值,这是它必须做的如果优先级会影响行为(假设它们已经是 RTL 关联的)。例如,请参阅 Luchian Crigore 的回答下的讨论。
也许这个错误是如此普遍,因为早期的 C++ 运算符优先表可能是从 C 表中复制和扩展的。也许错误一直存在,因为唯一的反例——a?b:c=d 形式的表达式——很少使用。也许吧。
【讨论】:
你会发现,在标准中:
58) 运算符的优先级不是直接指定的,但可以从语法中推导出来。 (注)
这意味着优先表是推断的,而不是指定的。只要他们的行为相同,你就可以说两者都是对的。因此,即使优先表将它们设置为具有相同的优先级,或者将三元放在赋值运算符之上,实际上也会发生同样的事情,因为语法。
请注意,associativity 在这里发挥了更大的作用(这也源于语法)。
即使您假设它们具有相同的优先级:
a = b ? c : d;
将被视为a = (b ? c : d),因为它们都是从右到左关联的。
【讨论】:
a?b:c=d 的解释。是(a?b:c)=d 还是a?b:(c=d)?
a?b:(c=d)。我已经说过在这种情况下关联性更重要。
(a?b:c)=d。