在if语句中,Objective-C #define宏评估不正确

时间:2013-10-29 18:16:46

标签: objective-c macros c-preprocessor

我很困惑为什么以下#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的不正确方法吗?如果是这样,我该怎么办?

4 个答案:

答案 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