2017-02-11 2 views
1

У меня этот простой код C с макро:Почему использование следующей макрофункции в C приводит к 1 вместо 2?

#include <stdio.h> 
#define MAX(x, y) x>y ? 1 : 0 

int main() { 
    int i = 9; 
    printf("%d\n", MAX(10, i) + 1); 
    return 0; 
} 

Теперь, как я понимаю функцию макросъемки, если значение х (которое равно 10) больше, чем значение у (которая 9 в этом случае), то макрос возвращает 1 другой нулевой нуль. Таким образом, не следует ли выводить выше 2 вместо 1 в этом случае после добавления 1 к окончательному результату макроса?

+0

Макросы не являются функциями, и они не возвращают вещи. Макросы - это замена текста (ну, замена токенов, действительно). Подключите фактический текст макроса на сайте использования, а '10' и' i' будут заменены словами 'x' и' y'. – user2357112

+0

Обратите внимание, что 'MAX' не является хорошим именем для этого макроса, так как я ожидаю, что он вернет либо' x', либо 'y', в зависимости от того, что больше. Возможно, 'IS_GREATER_THAN'? – isanae

ответ

2

Изменение #define MAX(x, y) x>y ? 1 : 0 до #define MAX(x, y) (x>y ? 1 : 0) устранит проблему.

C макро будет заменен непосредственно перед входом в компилятор, что означает, что условное выражение становится x > y ? 1 : 0 + 1, обе ветки станут 1.

Приоритет оператора + 1 переходит в условное выражение вместо него. В этом случае для принудительного приоритета требуется скобка.

Считается хорошей практикой всегда добавлять скобки для предотвращения такого неожиданного поведения в макросах. См. C programming book of K&R для получения полной информации.

+1

Но почему это так? – dikshant

+0

@ dikshant дизайнеры C думали, что этот способ лучше, чем другой вариант –

+0

@ M.M Для людей, которые играют на ассемблере, макросы - это трюки, которые приятно иметь. Но по прошествии времени, и компьютеры становятся более мощными, макросы становятся менее используемыми. –

4

MAX(10, i) + 1 заменяется именно с 10>i ? 1 : 0 + 1, который дает 1 в любом случае, из-за более высокого приоритета + над ?:.

Как правило, положить () вокруг замены и вокруг переменных

#define MAX(x, y) ((x)>(y) ? 1 : 0) 

, чтобы избежать проблем с очередностью.