Директивы арифметики в Objective-C - PullRequest
0 голосов
/ 18 декабря 2010

Моя проблема основана на директивах Objective-C и вычитании их. Ниже приведены мои директивы.

#define IS_IPAD FALSE
#define RECT_WIDTH IS_IPAD ? 725 : 280
#define RECT_PADDING IS_IPAD ? 50 : 10

Если я NSLog("@%d", RECT_WIDTH - RECT_PADDING), то получаю 50, а не 230. Почему это случилось? Единственный способ заставить его работать, это присвоить каждому значение типа int, а затем вычесть эти два.

Ответы [ 2 ]

6 голосов
/ 18 декабря 2010

Это из-за приоритета операций.Ваш код расширяется до следующего:

NSLog(@"%d", FALSE ? 725 : 280 - FALSE ? 50 : 10);

Что, после «круглых скобок» относительно правил приоритета оператора C, дает вам следующее:

NSLog(@"%d", FALSE ? 725 : ((280 - FALSE) ? 50 : 10));

Это частая проблема с макросами.Они расширяются почти как операция копирования-вставки, поэтому, если вы не позаботитесь об этом, у вас могут возникнуть проблемы с приоритетом оператора (как у вас сейчас).

У вас есть две возможности.Либо добавьте круглые скобки в ваши определения, чтобы этого не произошло:

#define RECT_WIDTH (IS_IPAD ? 725 : 280)
#define RECT_PADDING (IS_IPAD ? 50 : 10)

Или, поскольку это определяется во время компиляции, вы можете использовать директиву #if:

#if IS_IPAD == FALSE
 #define RECT_WIDTH 280
 #define RECT_PADDING 10
#else
 #define RECT_WIDTH 725
 #define RECT_WIDTH 50
#endif
0 голосов
/ 18 декабря 2010

Препроцессор превращает определенные макросы в следующий код C (просто представьте, что выполняете замену строки):

NSLog(@"%d", FALSE ? 725 : 280 - FALSE ? 50 : 10);

Теперь вы должны увидеть, в чем проблема.Тернарное выражение неоднозначно.

Вы можете обернуть круглые скобки вокруг выражений, чтобы обойти его:

#define IS_IPAD FALSE
#define RECT_WIDTH (IS_IPAD ? 725 : 280)
#define RECT_PADDING (IS_IPAD ? 50 : 10)

Или лучше использовать директиву #if.

#define IS_IPAD FALSE

#if IS_IPAD == TRUE
#define RECT_WIDTH 725
#define RECT_PADDING 50
#else
#define RECT_WIDTH 280
#define RECT_PADDING 10
#endif
...