2014-01-29 4 views
1

Для следующей программыОбъяснять выход следующей программы

#include <stdio.h> 
# 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); 
    return 0; 
} 

Я получаю этот выход, который я тестировал с различными компиляторами:

10 0 0 

Я понимаю, что он J было 5 и я был 10 выход был бы заменен. Но в этой конкретной программе оператор if не выполняется. Итак, может кто-то объяснить причину, почему я получаю этот выход?

+0

Было бы лучше, если бы вы просто написали три строки кода на месте. Здесь нет необходимости в макросе. –

ответ

4

Вам нужно обернуть макрос swap с кронштейнами.

if (i > j) 
{ 
    swap(i, j); 
} 

Не забывайте, что макрос просто операция копирования и вставки выполняются препроцессора, что приводит к следующему:

temp = i; 
i = j; 
j = temp; 

Если вы не обернуть его, вы в конечном итоге с:

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

Я не думаю, что это то, что вы хотели ... :)

0

После расширения макроса, код будет выглядеть

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

Это не то, что вы ожидаете нравится:

if(i > j) 
{ 
    temp=a; 
    a=b; 
    b=temp; 
} 
+0

Фактически он будет расширяться до 'temp = i; I = J; j = temp; ' –

+0

@JohnnyMopp; Да. Это была опечатка. – haccks

0
As an alternative to wrapping the macro in brackets... 
#define swap(a,b) {temp=a; a=b; b=temp;} 

You could also replace the semicolons to ensure the macro expands to a single statement... 
#define swap(a,b) temp=a, a=b, b=temp; 

Я предпочитаю подход «скобки», поскольку он лучше иллюстрирует область видимости.

1

Как отметили другие, ваш макрос swap приводит к трём утверждениям, и только первый из них становится частью инструкции if.

идиоматических способ написания такого макроса:

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

Хотя использование только скобки, опуская do и while (0), могут появиться на работу, она не будет выполнена в ситуациях, как это:

if (something) 
    swap(a, b); 
else 
    something 

В этом коде автор рассматривает swap как обычный вызов функции, не зная, что точку с запятой следует опустить. После предварительной обработки, это расширяется:

if (something) 
    { temp = a; a = b; b = temp; } 
; 
else 
    something 

Это приводит к ошибке компиляции, поскольку else не сразу следуют один оператор после if. Использование формы do … while (0) приводит к коду, так что swap(a, b); - это точно один оператор и может использоваться везде, где может использоваться обычный вызов функции в этой форме.

+0

+1 для включения подхода 'do {} while (0)' и проблем, которые могут возникнуть с его использованием (при определенных условиях). Вам не придется беспокоиться об этом, если вы всегда завершаете свои утверждения в '{}'. – bblincoe

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