C++中关于?和:的问题

9
为什么会有这个声明:
int a = 7, b = 8, c = 0;
c = b>a?a>b?a++:b++:a++?b++:a--;
cout << c;

不等于:
int a = 7, b = 8, c = 0;
c = (b>a?(a>b?a++:b++):a++)?b++:a--;
cout << c;

并且等于:
int a = 7, b = 8, c = 0;
c = b>a?(a>b?a++:b++):(a++?b++:a--);
cout << c;

请给我一些理由。为什么呢?

4
http://www.cppreference.com/wiki/operator_precedence - phimuemue
31
耶稣基督,你为什么要写那样的代码?! - Skilldrick
除非您知道优先级,否则应该使用括号编写代码。请注意书写规范。 - Zai
2
这段代码如果不清楚优先级,甚至对那些熟悉优先级、结合性等知识的人来说也很难理解。最好将其拆分为多行,并使用if语句。 - cHao
3个回答

15

? :是从右到左结合的。在语言中被定义为这样。


你知道吗,我认为你是对的,而我是错的。我会删除我的。 - Paul Tomblin

7

我相信 @sth 提供的答案是正确的,但我认为@Skilldrick在评论中说得对——你为什么要写这样的东西。

除了优先级问题外,在单个语句中递增相同变量时确实需要小心。 该语句中可能存在序列点,因此递增的顺序可能无法保证。 在不同编译器甚至相同编译器上的不同优化设置中,您可能会得到不同的结果。


2
绝对 - 在同一序列点上多次增加同一变量是可怕的未定义行为。那行代码可能合法地等于其中任何一个。 - Stewart
a ? b : c 的顺序是有保证的。 - anon
1
我可能错了,但是 ?: 不是那些保证评估顺序并在评估操作数之间具有序列点的运算符之一吗(其他运算符包括 ,&&|| 和可能还有其他一些)? - UncleBens
@Paul 嗯?我没有提到“贪婪”。 - anon
@Neil,你没有,但是如果你有? ? : :,它们如何关联是否已经定义了呢?@sth在他的回答中说过。我不知道这一点。 - Paul Tomblin
显示剩余4条评论

1
运算符&&||?:在表达式中执行流程控制。?:的行为类似于if-else语句。
c = b>a?a>b?a++:b++:a++?b++:a--;

if ( b>a )
    if ( a>b )
        a ++;
    else
        b ++;
else if ( a ++ )
    b ++;
else
    a --;

b>a? (
    a>b ?
        a ++
    :
        b ++
) : ( a ++ ?
    b ++
:
    a --
)

结合性是必要的,以实现类似于if … else if … else的行为。

有时我会使用类似于您的表达式进行词典序列比较:

operator< ()( arr &l, arr &r ) {
    return l[0] < r[0]? true
         : r[0] < l[0]? false
         : l[1] < r[1]? true
         : r[1] < l[1]? false
         : l[2] < r[2];
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接