意外结果,Gnu C中的三元运算符

时间:2012-03-19 00:07:47

标签: c conditional ternary-operator ternary operator-precedence

因此C中三元运算符的运算符优先级对我来说似乎真的很奇怪。一个很好的例子:

#include <stdio.h>

int main ()
{
   int i=5;
   int j=6;
   int k=7;
   printf("A: %d\n", i+j+(k!=7)?1:11); //prints 1
   printf("B: %d\n", i+j+((k!=7)?1:11)); //prints 22
   return 0;
}

这似乎与这里的问题类似:
C++ ternary conditional and assignment operator precedence
Ternary operator evaluation order

作为澄清,我理解括号使其有效,正如我在原帖中的评论所表明的那样......

我只是想知道为什么语言作者会选择一种很有可能欺骗人们的评估方法,当第一个语句似乎可以在编译器方面被认为是有效的。

但是这些问题涉及左侧或类成员中的操作员,因为这种奇怪的行为发生在RHS上。

2 个答案:

答案 0 :(得分:6)

这里有什么奇怪的?第一部分解释为:

(11 + (k != 7)) ? 1 : 11

,第二个被解释为

 11 + ((k !=7) ? 1 :11)

第一个是由优先规则引起的(二进制算术的优先级高于三元运算符),第二个是通过用括号分组表达式来绕过优先规则。

您的编辑询问原因,通常只能猜测那些原因,除非当时在场的C委员会有人来帮忙。我的猜测是,使用复杂表达式并询问其真值比使用三元运算符来确定算术中表达式的值更为常见。想到这样的事情:

return (froble() + 3) == 0 ? 23 : 5; // parens for sanity but works without

如果将其解释为return (froble() + 3) == 5;,我会感到非常震惊。

答案 1 :(得分:0)

一个人应该选择一个非常高或非常低的优先级,而一个人会对做出错误假设的人感到惊讶。

选择低优先级的一个有用的原因是它意味着运算符的函数类似于if .. then .. else ..构造而没有任何大括号,这可能意味着编译器编写者(可能使用相同的代码)的工作量较少处理两者),以及理解优先级的编码员直接重构。

在实践中,该语言可能标准化了在预标准化时代编写的代码中最常用的优先级。