运算符+
的优先级高于<<
C++,这意味着表达式a << b + c << d
应计算为:
a << (b + c) << d
但这没有任何意义。跟随时可以获得更多的意义
a << (b + (c << d))
但这违反了+
over的优先级<<
,不是吗?编译器如何评估“确实有意义”部分?
更新:当问这个问题时,我认为编译器使用了第二个变体,这就是为什么我想知道编译器是如何进行这个评估的。事实上,使用了第一个并且它是正确的。
运算符+
的优先级高于<<
C++,这意味着表达式a << b + c << d
应计算为:
a << (b + c) << d
但这没有任何意义。跟随时可以获得更多的意义
a << (b + (c << d))
但这违反了+
over的优先级<<
,不是吗?编译器如何评估“确实有意义”部分?
更新:当问这个问题时,我认为编译器使用了第二个变体,这就是为什么我想知道编译器是如何进行这个评估的。事实上,使用了第一个并且它是正确的。
“有意义”是主观的。这就是为什么编译器不评估“意义”,而是基于一组规则的语法。因为<<
具有更高的优先级(由这些规则集给出),它将表达式计算为
a << (b + c) << d
如有疑问,请使用括号。
编译器不考虑什么是有意义的。他们只是遵守规则。
制定规则的是语言的设计者,他们通常会尝试制定这些规则以使它们有意义。当然,在一个人看来是明智的,在另一个人看来却是奇怪的。真的没有办法解决这个问题。
operator <<
的优先级低于operator +
。参见维基百科。
编译器不会试图理解是否有任何意义。他们只是遵循语法规则。要真正了解为什么左移的优先级低于加号,您可能应该问丹尼斯里奇的鬼魂。
除此之外,如果一个语法想要给出你想要的优先级,它应该以相同的优先级(和从左到右的关联性)进行左移和加号。
但是,如果您想到这样的用例:
unsigned int a, b, mid;
...
mid = a + b >> 1;
那么首先计算是完全有意义的a + b
。所以我认为最初设计 C 时,他们决定移位是在常见的数学算术之后进行的。
在 C++ 中,这甚至让事情变得更舒服。现在的方式,你可以写:
cout << a + b << endl;
不需要括号。尽管这只是一个快乐的巧合,并且与这些优先级的原始原因没有任何关系。
在这种情况下,编译器会寻找最高优先级的运算符并计算相应的运算。它命中 + 和 sum b & c。然后剩下两个 << 运算符,编译器按顺序处理它们