我目前正在使用C++入门这本书学习C++,书中的练习之一是:
解释以下表达式的作用:
someValue ? ++x, ++y : --x, --y
我们知道些什么?我们知道三元运算符比逗号运算符具有更高的优先级。对于二元运算符,这很容易理解,但对于三元运算符,我有点困难。使用二元运算符“具有更高的优先级”意味着我们可以使用括号将具有更高优先级的表达式括起来,并且它不会改变执行。
对于三元运算符,我会这样做:
(someValue ? ++x, ++y : --x, --y)这实际上导致了相同的代码,这不能帮助我理解编译器将如何对代码进行分组。
但是,通过使用C++编译器进行测试,我知道表达式是可以编译的,而我不知道:运算符本身能代表什么。因此,编译器似乎正确地解释了三元运算符。
然后,我以两种方式执行该程序:
#include <iostream>
int main()
{
bool someValue = true;
int x = 10, y = 10;
someValue ? ++x, ++y : --x, --y;
std::cout << x << " " << y << std::endl;
return 0;
}结果如下:
11 10另一方面,使用someValue = false时,它会打印:
9 9为什么C++编译器生成的代码对于三元运算符的真分支仅递增x,而对于三元运算符的假分支则同时递减x和y
我甚至用括号将true-branch括起来,如下所示:
someValue ? (++x, ++y) : --x, --y;但它仍然会导致11 10。
发布于 2017-11-29 03:18:55
正如@Rakete在他们出色的回答中所说,这是棘手的。我想补充一点。
三元运算符必须具有以下形式:
逻辑或表达式
?表达式:赋值-表达式
因此,我们有以下映射:
someValue:logical-or-expression++x, ++y:expression--x, --y还是仅为--x事实上,它只是--x,因为赋值表达式不能被解析为两个用逗号分隔的表达式(根据C++的语法规则),因此--x, --y不能被视为赋值表达式。
这将导致三元(条件)表达式部分如下所示:
someValue?++x,++y:--x从可读性的角度考虑,将++x,++y计算为带括号的(++x,++y)可能会有所帮助;?和:之间的任何内容都将在条件之后进行排序。(在接下来的文章中,我将把它们括起来)。
并按以下顺序进行计算:
someValue?(++x,++y)或--x (取决于1的bool结果)然后,该表达式被视为逗号运算符的左子表达式,右子表达式为--y,如下所示:
(someValue?(++x,++y):--x), --y;这意味着左边是一个丢弃的值表达式,这意味着它肯定是被求值的,但是我们计算右边并返回它。
那么当someValue为true时会发生什么呢?
(someValue?(++x,++y):--x)执行并将x和y递增为11,左侧表达式被丢弃(尽管递增的副作用仍然存在)--y的右侧,然后将y递减返回be为了“修复”这个行为,你可以用圆括号将表达式分组,把它转换成一个主表达式,这个表达式是一个赋值表达式*的有效条目。
someValue?++x,++y:(--x, --y);*这是一个相当有趣的长链,将一个赋值表达式连接回一个主表达式:
赋值表达式-(可以包含) -->条件表达式-->逻辑或表达式-->逻辑与表达式-->包含或表达式-->异或表达式-->与表达式-->等式表达式-->关系表达式-->移位表达式-->加法表达式-->乘法表达式--> pm表达式-->强制转换表达式-->后缀表达式-->主表达式
发布于 2017-11-29 02:57:09
哇,这很棘手。
编译器将您的表达式视为:
(someValue ? (++x, ++y) : --x), --y;三元运算符需要一个:,它不能在该上下文中独立存在,但是在它之后,没有理由认为逗号应该属于false大小写。
现在,它可能更有意义,为什么你会得到这样的输出。如果someValue为真,则执行++x、++y和--y,这不会有效地更改y,但会向x添加一个。
如果someValue为false,则执行--x和--y,将它们都减1。
发布于 2017-11-29 02:57:51
为什么C++编译器要为三元运算符的真分支生成仅递增
x的代码
你曲解了所发生的事情。true-branch同时递增x和y。但是,在此之后,y会立即无条件地递减。
这是如何实现的:从the conditional operator has higher precedence than comma operator in C++开始,编译器按如下方式解析表达式:
(someValue ? ++x, ++y : --x), (--y);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^注意逗号后面的“孤立”--y。这就是导致最初递增的y递减的原因。
我甚至用圆括号将
分支括起来,如下所示:
someValue?(++x,++y):--x,--y;
您在正确的路径上,但是您将错误的分支括起来:您可以通过将else分支括起来来解决这个问题,如下所示:
someValue ? ++x, ++y : (--x, --y);https://stackoverflow.com/questions/47538906
复制相似问题