我很困惑为什么以下#define
宏在以下if语句中使用时未按预期进行评估:
#define kOffsetX 2048.0
#define kPositionX (screenSize.width * (kOffsetX/2048.0))-10.0
CGSize screenSize = [CCDirector sharedDirector].winSize;
float potentialPosition = 486.86f;
float playersFieldOffset = 1.0;
if ((potentialPosition - kPositionX) * playersFieldOffset > 0.0) {
请注意,kPositionX的评估结果为470.0。当486-470明显大于零时,if语句的计算结果为FALSE。但是,如果我在kPositionX周围加上括号,那么if语句正确地计算为TRUE。
为什么会这样?这是使用#define
的不正确方法吗?如果是这样,我该怎么办?
答案 0 :(得分:4)
预处理器只是按其定义替换所有宏,所以
potentialPosition - kPositionX
扩展为
potentialPosition - (screenSize.width * (2048.0/2048.0))-10.0
,在运行时评估时,给出
486.86 - 480 - 10 = -3.14 < 0
您应该始终将表达式括在括号中的宏中:
#define kPositionX ((screenSize.width * (kOffsetX/2048.0))-10.0)
以便扩展给出
potentialPosition - ((screenSize.width * (2048.0/2048.0))-10.0)
这是你所期望的。
这是预处理器宏的(缺点之一)缺点。或者,你可以 使用例如(内联)函数,请参阅Inline functions vs Preprocessor macros 了解更多信息。
答案 1 :(得分:1)
每当使用#define时,请确保将#define的全部内容包装在括号中。这将防止发生任何不正确的操作计算顺序。因此,将#defines更改为
#define kOffsetX (2048.0)
#define kPositionX ((screenSize.width * (kOffsetX/2048.0))-10.0)
答案 2 :(得分:1)
#define
个宏是文字表达式!在拼接任何参数之后(并且您没有为此宏使用任何参数),宏基本上直接插入到代码中。所以,虽然你期待
if ((potentialPosition - kPositionX) * playersFieldOffset > 0.0)
变成
if ((potentialPosition - (answer of kPositionX) * playersFieldOffset > 0.0)
它实际上变成了
if ((potentialPosition - (screenSize.width * (kOffsetX/2048.0)) - 10.0) * playersFieldOffset > 0.0)
哪个评估不正确。您可以通过围绕括号中的整个宏来解决这个问题。
#define kPositionX ((screenSize.width * (kOffsetX/2048.0)) - 10.0)
或者,如你所说,用括号围绕kPositionX
if ((potentialPosition - (kPositionX)) * playersFieldOffset > 0.0) {
此外,作为良好实践的一般规则,宏通常以所有大写字母书写,下划线(_)显示单词之间的中断。 #define MACRO_NUMBER_ONE
答案 3 :(得分:1)
宏通过字符串替换工作。您的宏kPositionX
的格式为(a) - b ,因此当您在子表达式(potentialPosition - kPositionX)
中使用它时,结果为:
(potentialPosition - (screenSize.width * (kOffsetX/2048.0)) - 10.0)
其中10.0
从potentialPosition
中扣除 。可能你想要:
(potentialPosition - ((screenSize.width * (kOffsetX/2048.0)) - 10.0))
请注意额外的括号 - 其中10.0
已添加 {/ 1>}。
您必须始终记住,宏在定义时使用字符串替换,并且包含表达式的任何宏都应具有外部括号以避免出现问题:
potentialPosition