Макросы C и использование аргументов в скобках - PullRequest
12 голосов
/ 25 августа 2011

Пример

#define Echo(a)  a
#define Echo(a) (a)

Я понимаю, что здесь, вероятно, нет существенной разницы, но почему вы хотите добавить a в круглые скобки внутри тела макроса?Как это меняет это?

Ответы [ 2 ]

13 голосов
/ 25 августа 2011

Предположим, у вас есть

#define mul(x, y)  x * y

Что произойдет, если я скажу:

mul(a + 5, 6); /* a + 5 * 6 */

Теперь, если я немного изменю макрос:

#define mul(x, y)  ((x) * (y))
mul(a + 5, 6); /* ((a + 5) * (6)) */

Помните, чтоаргументы не оцениваются или что-либо, выполняется только текстовая подстановка.

EDIT

Для объяснения того, что весь макрос указан в скобках, см. ссылка , опубликованная Нейт СК .

1 голос
/ 10 февраля 2018

Только для записи, я приземлился отсюда Как исправить математические ошибки при использовании макросов , и я постараюсь расширить этот Ответ здесь, чтобы он соответствовал другому.

Вы спрашиваетео разнице в:

#define Echo( a )  a
#define Echo( a ) ( a )

, что хорошо, если вы сами не понимаете макрос (я тоже не эксперт :)).

Прежде всего, вы уже(вероятно) знают, что есть приоритет оператора, поэтому существует огромная разница между этими двумя программами:

1):

#include <stdio.h>
#define ADD( a , b ) a + b

int main( void )
{
    auto const int a = 5;
    auto const int b = 10;

    auto const int c = ADD (  2 + a ,  2 + b );
    printf( "%d", c );
    return 0;
}

Вывод:

19

и:

#include <stdio.h>
#define ADD( a , b ) ( a ) + ( b )

int main( void )
{
    auto const int a = 5;
    auto const int b = 10;

    auto const int c = ADD ( a , b );
    printf( "%d", c );
    return 0;
}

Вывод:

15

Теперь давайте заменим + на *:

#define ADD( a, b ) a * b

Компиляторобрабатывает a * b как например a == 5 и b == 10, что делает 5 * 10.

Но, когда вы говорите: ADD ( 2 + a * 5 + b ) Как здесь:

#include <stdio.h>
#define ADD( a , b ) ( a ) * ( b )

int main( void )
{
    auto const int a = 5;
    auto const int b = 10;

    auto const int c = ADD ( 2 + a , 5 + b );
    printf( "%d", c );
    return 0;
}

Вы получаете 105, поскольку приоритет оператора задействован и обрабатывает

2 + b * 5 + a

как

( 2 + 5 ) * ( 5 + 10 )

, что составляет

( 7 ) * ( 15 ) == 105

Но когда вы делаете:

#include <stdio.h>
#define ADD( a, b ) a * b

int main( void )
{
    auto const int a = 5;
    auto const int b = 10;

    auto const int c = ADD ( 2 + a , 5 + b );
    printf( "%d", c );
    return 0;
}

, вы получаете 37 из-за

 2 + 5 * 5 + 10

, что означает:

2 + ( 5 * 5 ) + 10

, что означает:

2 + 25 + 10

Короткий ответ, существует большая разница между:

#define ADD( a , b ) a * b

и

#define ADD( a , b ) ( a ) * ( a )
...