C # определить макросы

Вот что у меня есть, и мне интересно, как это работает и что на самом деле делает.

#define NUM 5
#define FTIMES(x)(x*5)

int main(void) {
    int j = 1;
    printf("%d %d\n", FTIMES(j+5), FTIMES((j+5)));
}

Он производит два целых числа: 26 и 30.

Как оно это делает?


person Community    schedule 26.01.2009    source источник


Ответы (7)


Причина, по которой это происходит, заключается в том, что ваш макрос расширяет печать до:

printf("%d %d\n", j+5*5, (j+5)*5);

Имея в виду:

1+5*5 and (1+5)*5
person Serafina Brocious    schedule 26.01.2009
comment
Это должно послужить ценным уроком, как избегать использования макросов #define для вещей, с которыми на самом деле должны работать встроенные функции. - person Calyth; 26.01.2009
comment
Или, когда вы не можете избежать их, поместите каждое вхождение каждого аргумента в круглые скобки и поместите весь макрос в круглые скобки (то есть, когда ваш макрос является выражением, а не оператором) - person ; 26.01.2009

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

#define FTIMES(x) ((x)*5)

Скобки вокруг x в расширении макроса предотвращают проблему ассоциативности операторов.

person Greg Hewgill    schedule 26.01.2009
comment
это не спасет вас, если у вас есть несколько вхождений параметра в макросе, и вы передаете какое-то выражение с побочными эффектами, например j += 3. - person rmeador; 26.01.2009

определить - это просто замена строки.

Ответ на ваш вопрос после этого - порядок операций:

FРАЗ(j+5) = 1+5*5 = 26

FРАЗ((j+5)) = (1+5)*5 = 30

person Joe    schedule 26.01.2009

Предварительный процесс компилятора просто подставляет FTIMES везде, где он его видит, а затем компилирует код. Итак, на самом деле код, который видит компилятор, таков:

#define NUM 5
#define FTIMES(x)(x*5)

int main(void)
{

    int j = 1;

    printf("%d %d\n", j+5*5,(j+5)*5);
}

Затем, принимая во внимание предпочтения оператора, вы можете понять, почему вы получаете 26 и 30.

person casperOne    schedule 26.01.2009
comment
Технически компилятор не видит #define. :) - person Greg Hewgill; 26.01.2009

И если вы хотите это исправить:

#define FTIMES(x) ((x) * 5)
person Sean Bright    schedule 26.01.2009

препроцессор заменяет все NUM вхождения в коде на 5 и все FTIMES(x) на x * 5. Затем компилятор компилирует код.

Это просто замена текста.

person Megacan    schedule 26.01.2009

Порядок операций.

FTIMES(j+5), где j=1 оценивается как:

1+5*5

Который:

25+1

=26

Создав FTIMES((j+5)) вы изменили его на:

(1+5)*5

6*5

30

person Eddie Parker    schedule 26.01.2009