2014-01-26 4 views
1

Так что я следующая программа:C: Ложные состояние интерпретируется как верно, если заявление

# define swap(a,b) temp=a; a=b; b=temp; 

int main() { 
int i, j, temp; 
i = 5; 
j = 10; 
temp = 0; 
if (i > j) 
    swap(i, j); 
printf("%d %d %d", i, j, temp); 
} 

Это приводит к:

10, 0, 0 

То, что я не понимаю, почему if (5 > 10) Условие выполнено как «истинное», хотя 5 не больше 10.

+1

Результат 10, 0, 0 должна дать вам подсказку, что это не о состоянии оценивая к истине. –

ответ

7

Это должно научить вас избегать макросов, если это возможно, и всегда, всегда использовать фигурные скобки в операциях управления потоком.

После макроподстановок, ваш код будет читать:

if (i > j) 
    temp = i; 
i = j; 
j = temp; 

Смотрите эту проблему?

+0

Я не знал, как работали макросы, поэтому это меня сбивало с толку, я думал, что он называется как функция, но вместо этого он заменяется во время компиляции, и, поскольку нет скобок, только первое утверждение «temp = i» падает внутри утверждения if, имеет смысл, спасибо! –

+2

@EricBergman: Этот аспект макросов порождает целый ряд подводных камней. Классические примеры: '#define add (x, y) x + y' (try' add (1, 2) * 3') и многократная оценка аргументов. Вот почему в макросах производства вы видите все, что обернуто до смерти внутри parens и брекетов. – Jon

+0

В вашем опыте есть ли смысл использовать макросы? Если вы можете сделать обычную функцию, почему когда-либо используете макросы? Я вижу, что вы упомянули «производственные макросы», поэтому кажется, что это то, что широко используется для определенной цели. –

3

Это потому, что во время компиляции swap(i, j); заменяется на temp=a; a=b; b=temp;. Теперь расширенный макрос выглядит

if(i > j) 
    temp = i; 
    i = j; 
    j = temp; 

Во время исполнения только temp = i не будет выполнять для i > j быть false.
Если вы хотите лечить swap(i, j) как функцию, а затем изменить определение макроса

#define swap(a,b) do {temp=a; a=b; b=temp;} while (0) 
+0

Имеет смысл, этот вопрос «трюк» был представлен мне на собеседовании, но поскольку я не знал, как работают макросы, я ошибся. Я думал, что это похоже на обычный вызов функции. Спасибо. –

+1

@ EricBergman; См. Редактирование. Теперь ваш код будет работать так, как должен. – haccks

Смежные вопросы