如果我定义了一个数字的绝对值作为如何评估此声明?
#define ABS(X) X >= 0 ? X : (-1) * X
会有什么
ABS(2) + ABS(-3)
评估为?我的朋友声称其评估为2.
如果我定义了一个数字的绝对值作为如何评估此声明?
#define ABS(X) X >= 0 ? X : (-1) * X
会有什么
ABS(2) + ABS(-3)
评估为?我的朋友声称其评估为2.
如果键入:
ABS(2) + ABS(-3)
这将取代出来:
2 >= 0 ? 2 : (-1) * 2 + -3 >= 0 ? -3 : (-1) * -3
可以打破下来:
2 >= 0 ? 2 : -5 >= 0 ? -3 : (-1) * -3
或者:
2 >= 0 ? 2 : (-5 >= 0 ? -3 : (-1) * -3)
第一部分(2 >= 0
)的计算结果为true,因此计算结果为2
。
需要注意的是,你可以很容易地通过编写宏为解决这个问题:
#define ABS(X) ((X) >= 0 ? (X) : (-1) * (X))
这将使评估顺序符合市场预期,并导致其解析为5,而不是2,话虽这么说,使用内联函数会更干净,并避免整个场景。
通过将它包装在parens中,您对宏的修复不适用于所有情况。考虑'ABS(t> = 0?-1:1)'。这不会像人类预期的那样扩大。对于宏,通常将参数包装在parens中,并包装整个宏:'#define ABS(X)((X)> = 0?(X):(-1)*(X))' t处理所有的情况,尤其是X有副作用的情况下,但它确实相当好) – abelenky
@abelenky True - 在括号内包裹内部'X'以尝试在我的答案中处理这个问题。好点子。 –
预处理器执行基于文本(实际上是基于标记的)替换。它不关注逻辑表达式分组。
鉴于
#define ABS(X) X >= 0 ? X : (-1) * X
ABS(2)
扩展到
2 >= 0 ? 2 : (-1) * 2
和
ABS(-3)
扩展到
-3 >= 0 ? -3 : (-1) * -3
所以
ABS(2) + ABS(-3)
扩展到
2 >= 0 ? 2 : (-1) * 2 + -3 >= 0 ? -3 : (-1) * -3
现在看运营商的分组方式,你就会明白为什么5直观的答案是不正确的。
我是这样看的:
ABS(2) + ABS(-3)
变为:
2 >= 0 ? 2 : (-1) * 2 + -3 >= 0 ? -3 : (-1) * -3
添加一些括号澄清:
(2 >= 0) ? 2 : (((-1) * 2 + -3 >= 0) ? -3 : (-1) * -3)
和评估:
2其实> = 0,因此:
(以及其他所有内容,从(((-1
开始,将被忽略)
所以,我同意你的朋友。
这是C预处理器;你*不能*假设不在那里的人。 CPP执行纯文本替换。 – michaelb958
我没有做任何关于parens的假设。我按照正常的操作顺序放置它们,只是为了帮助人们理解。如果我妥善安置它们,它们根本不会改变电脑解释。 – abelenky
这会教我盲目地曲解东西......我只是假设你正在冲入并重新强制要求5的“正确”结果。对不起。 – michaelb958
你为什么不试试并找出答案? –
那么我也想知道为什么。 – Jessica
'2> = 0? 2:(-1)* 2 + -3> = 0? -3:(-1)* -3' – dyp