int x = 5,y = 10;
bool boolean = 0;
int k = (boolean ? ++x, ++y : --x, --y);
cout<<k;
当布尔值为0时,它输出9,但是当它为1时输出10.我知道这是因为优先级而发生,但无法准确弄清楚它是如何发生的,请帮助我理解这一点。
注意:我知道如果使用括号,我可以得到预期的输出,或者更好地编写一个干净的代码,我只是用它来理解编译器如何根据优先级来评估这些表达式。
答案 0 :(得分:40)
,
的优先级低于?:
。这意味着完整的括号是:
int k = ((boolean ? (++x, ++y) : --x), --y);
如您所见,k
始终初始化为--y
的值。只是如果boolean
为true
,则++y
在此之前发生。
在查找表达式的完整括号形式时,请将其视为构造表达式树(其中最低优先级运算符位于根目录中)。
在表达式中查找最低优先级运算符,并将其左侧参数及其右侧参数括起来。在带括号的子表达式中递归重复。
答案 1 :(得分:22)
由于逗号运算符的operator precedence最低,因此您的语句实际上等于
k = (boolean ? (++x, ++y) : --x), --y;
这意味着当boolean
为true
时,您都会增加和减少y
。在这两种情况下都会丢弃三元表达式的结果,而k
仅被赋予--y
的结果。
应该注意,这不是未定义的行为,因为逗号运算符引入了一个序列点。
要获得您期望的结果,您需要执行
k = boolean ? (++x, ++y) : (--x, --y);
请注意,++x, ++y
周围的括号是严格不需要的,但它确实使表达式更清晰。
答案 2 :(得分:8)
鉴于上述优秀答案,我们应该写一下:
if (boolean) {
++x;
++y;
} else {
--x;
--y;
}
int k = y;
因为代码在其意图中更强可读和清除。这将有助于任何必须维护代码的人(包括原作者!),无需任何人通过询问SO问题或担心,
或?:
的优先权或任务的后勤而浪费时间这样一个复杂的表达方式。任何现代编译器都会将此和上述内容优化为相同的结果代码