#define used with operators [duplicate]

你说的曾经没有我的故事 提交于 2020-01-30 11:08:07

问题


I know that #define has the following syntax: #define SYMBOL string If I write, for example

#define ALPHA 2-1
#define BETA ALPHA*2

then ALPHA = 1 but BETA = 0.(why ?)

But if i write something like this

#define ALPHA (2-1)
#define BETA ALPHA*2

then ALPHA = 1 and BETA = 2.

Can someone explain me what's the difference between those two ?


回答1:


Pre-processor macros created using #define are textual substitutions.

The two examples are not equivalent. The first sets BETA to 2-1*2. The second sets BETA to (2-1)*2. It is not correct to claim that ALPHA == 1 as you do, because ALPHA is not a number - it is a free man! it's just a sequence of characters.

When parsed as C or C++, those two expressions are different (the first is the same as 2 - (1*2)).

We can show the difference, by printing the string expansion of BETA as well as evaluating it as an expression:

#ifdef PARENS
#define ALPHA (2-1)
#else
#define ALPHA 2-1
#endif

#define BETA ALPHA*2

#define str(x) str2(x)
#define str2(x) #x

#include <stdio.h>
int main()
{
    printf("%s = %d\n", str(BETA), BETA);
    return 0;
}

Compile the above with and without PARENS defined to see the difference:

(2-1)*2 = 2
2-1*2 = 0

The consequence of this is that when using #define to create macros that expand to expressions, it's generally a good idea to use many more parentheses than you would normally need, as you don't know the context in which your values will be expanded. For example:

#define ALPHA (2-1)
#define BETA ((ALPHA)*2)



回答2:


Macro (#define ...) are only text replacement.

With this version:

#define ALPHA 2-1
#define BETA ALPHA*2

The preprocessor replace BETA by ALPHA*2 then replace ALPHA by 2-1. When the macro expansion is over, BETA is replaced by 2-1*2 which is (due to operator precedence) equal to 2-(1*2)=0

When you add the parenthesis around the "value of ALPHA" (ALPHA doesn’t really have a value since macro are just text replacement), you change the order of evaluation of the operation. Now BETA is replaced by (2-1)*2 which is equal to 2.




回答3:


Order of operations. The first example become 2-1*2, which equals 2-2. The second example, on the other hand, expands to (2-1)*2, which evaluates to 1*2.

In the first example:

#define ALPHA 2-1
#define BETA ALPHA*2

alpha is substituted directly for whatever value you gave it (in this case, 2-1). This leads to BETA expanding into (becoming) 2-1*2, which evaluates to 0, as described above.

In the second example:

#define ALPHA (2-1)
#define BETA ALPHA*2

Alpha (within the definition of BETA) expands into the value it was set to(2-1), which then causes BETA to expand into (2-1)*2 whenever it is used.

In case you're having trouble with order of opeartions, you can always use the acronym PEMDAS to help you (Parenthesis Exponent Multiplication Division Addition Subtraction), which can itself be remembered as "Please Excuse My Dear Aunt Sally". The first operations in the acronym must always be done before the later operations in the acronym (except for multiplication and division (in which you just go from left to right in the equation, since they are considered to have an equal priority, and addition and subtraction (same scenario as multiplication and division).




回答4:


macros in c/c++ are just text substitutions, not functions. So the macro is there just to replace a macro name in the program text with its contents before the compiler event tries to analyze the code. So in the first case the compiler will see this:

BETA ==> ALPHA * 2 ==> 2 - 1 * 2 ==> compiler ==> 0
printf("beta=%d\n", BETA); ==> printf("beta=%d\n", 2 - 1 * 2);

In the second

BETA ==> ALPHA * 2 ==> (2 - 1) * 2 ==> compiler ==> 2
printf("beta=%d\n", BETA); ==> printf("beta=%d\n", (2 - 1) * 2);


来源:https://stackoverflow.com/questions/45352166/define-used-with-operators

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!