这个三元条件表达式是如何执行的?

时间:2016-02-26 15:08:58

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

int x = 5,y = 10;
bool boolean = 0;
int k = (boolean ? ++x, ++y : --x, --y);
cout<<k;

当布尔值为0时,它输出9,但是当它为1时输出10.我知道这是因为优先级而发生,但无法准确弄清楚它是如何发生的,请帮助我理解这一点。

注意:我知道如果使用括号,我可以得到预期的输出,或者更好地编写一个干净的代码,我只是用它来理解编译器如何根据优先级来评估这些表达式。

3 个答案:

答案 0 :(得分:40)

,的优先级低于?:。这意味着完整的括号是:

int k = ((boolean ? (++x, ++y) : --x), --y);

如您所见,k始终初始化为--y的值。只是如果booleantrue,则++y在此之前发生。

在查找表达式的完整括号形式时,请将其视为构造表达式树(其中最低优先级运算符位于根目录中)。

在表达式中查找最低优先级运算符,并将其左侧参数及其右侧参数括起来。在带括号的子表达式中递归重复。

答案 1 :(得分:22)

由于逗号运算符的operator precedence最低,因此您的语句实际上等于

k = (boolean ? (++x, ++y) : --x), --y;

这意味着当booleantrue时,您都会增加和减少y。在这两种情况下都会丢弃三元表达式的结果,而k仅被赋予--y的结果。

应该注意,这不是未定义的行为,因为逗号运算符引入了一个序列点。

要获得您期望的结果,您需要执行

k = boolean ? (++x, ++y) : (--x, --y);

请注意,++x, ++y周围的括号是严格不需要的,但它确实使表达式更清晰。

答案 2 :(得分:8)

鉴于上述优秀答案,我们应该写一下:

if (boolean) {
     ++x;
     ++y;
} else {
     --x;
     --y;    
}
int k = y;

因为代码在其意图中更强可读清除。这将有助于任何必须维护代码的人(包括原作者!),无需任何人通过询问SO问题或担心,?:的优先权或任务的后勤而浪费时间这样一个复杂的表达方式。任何现代编译器都会将此和上述内容优化为相同的结果代码