[英]Macro expansion in context of arithmetic expression?
I saw this below code in an website. 我在网站上看到了以下代码。 I could not able to understsnd how the result is coming as
11
, instead of 25
or 13
. 我无法判断结果如何变为
11
,而不是25
或13
。
Why I am thinking 25
because SQ(5) 5*5
为什么我在想
25
因为SQ(5) 5*5
or 13
because 或
13
因为
SQ(2) = 4;
SQ(3) = 9;
may be final result will be 13 (9 + 4)
But surprised to see result as 11
. 可能是最终结果将是
13 (9 + 4)
但是惊讶地看到结果为11
。 How the result is coming as 11
? 结果如何成为
11
?
using namespace std;
#define SQ(a) (a*a)
int main()
{
int ans = SQ(2 + 3);
cout << ans << endl;
system("pause");
}
The preprocessor does a simple text substitution on the source code. 预处理器在源代码上执行简单的文本替换。 It knows nothing about the underlying language or its rules.
它对基础语言或其规则一无所知。
In your example, SQ(2 + 3)
expands to (2 + 3*2 + 3)
, which evaluates to 11
. 在您的示例中,
SQ(2 + 3)
扩展为(2 + 3*2 + 3)
,其值为11
。
A more robust way to define SQ
is: 定义
SQ
更健壮的方法是:
#define SQ(a) ((a)*(a))
Now, SQ(2 + 3)
would expand to ((2 + 3)*(2 + 3))
, giving 25
. 现在,
SQ(2 + 3)
将扩展为((2 + 3)*(2 + 3))
,得到25
。
Even though this definition is an improvement, it is still not bullet-proof. 虽然这个定义是一种改进,但它仍然不是防弹的。 If
SQ()
were applied to an expression with side effects , this could have undesired consequences. 如果将
SQ()
应用于具有副作用的表达式,则可能会产生不良后果。 For example: 例如:
f()
is a function that prints something to the console and returns an int
, SQ(f())
would result in the output being printed twice. f()
是一个向控制台输出内容并返回int
的函数,则SQ(f())
将导致输出被打印两次。 i
is an int
variable, SQ(i++)
results in undefined behaviour . i
是int
变量,则SQ(i++)
导致未定义的行为 。 For further examples of difficulties with macros, see Macro Pitfalls . 有关宏的困难的更多示例,请参阅宏陷阱 。
For these reasons it is generally preferable to use functions rather than macros. 由于这些原因,通常优选使用函数而不是宏。
#define
expansions kick in before the compiler sees the source code. #define
扩展在编译器看到源代码之前启动。 That is why they are called pre-processor directives , the processor here is the compiler that translates C to machine readable code. 这就是为什么它们被称为预处理器指令 ,这里的处理器是将C转换为机器可读代码的编译器。
So, this is what the macro pre-processor is passing on to the compiler: 所以,这就是宏预处理器传递给编译器的原因:
SQ(2 + 3)
is expanded as (2 + 3*2 + 3)
SQ(2 + 3)
扩展为(2 + 3*2 + 3)
So, this is really 2 + 6 + 3
= 11
. 所以,这真的是
2 + 6 + 3
= 11
。
How can you make it do what you expect? 你怎么能让它做你期望的?
The C preprocessor does textual substitution before the compiler interprets expressions and C syntax in general. C预处理器在编译器解释表达式和C语法之前进行文本替换。 Consequently, running the C preprocessor on this code converts:
因此,在此代码上运行C预处理器会转换:
SQ(2 + 3)
into: 成:
2 + 3*2 + 3
which simplifies to: 这简化为:
2 + 6 + 3
which is 11. 这是11。
It's just a replacement before compilation 它只是在编译之前的替代品
so you should try this out : 所以你应该试试这个:
#define SQ(a) ((a)*(a))
In your case , SQ(2 + 3)
is equivalent to (2+3*2+3)
which is 11
. 在您的情况下,
SQ(2 + 3)
相当于(2+3*2+3)
,即11
。
But correcting it to as I wrote above, it will be like, ((2+3)*(2+3))
which is 5*5 = 25
that's the answer you want. 但正如我在上面所写的那样纠正它,它会像
((2+3)*(2+3))
,即5*5 = 25
,这就是你想要的答案。
#define preprocesor #define preprocesor
Syntax : # define identifier replacement 语法: #define identifier replacement
# define can work also with parameters to define function macros: #define也可以使用参数来定义函数宏:
# define SQ(a) (a*a)
will replace any occurance of SQ(a) with a*a at compile time. 将在编译时用* a替换任何SQ(a)的出现。 Hence,
因此,
SQ(2+3) will be replaces by 2+3*2+3 The computation is performed after the replacement is done. SQ(2 + 3)将被替换为2 + 3 * 2 + 3在更换完成后执行计算。 hence answer 2+3*2+3=11
因此回答2 + 3 * 2 + 3 = 11
For your implementation, the value will expand to 2+3 * 2+3
which will result into 2+6+3=11. 对于您的实现,该值将扩展为
2+3 * 2+3
,这将导致2 + 6 + 3 = 11。
You should define it as: 您应该将其定义为:
#define SQ(x) ({typeof(x) y=x; y*y;})
Tested on gcc
, for inputs like 测试
gcc
,输入如
Note: typeof
is GNU addition to standard C. May not be available in some compilers. 注意:
typeof
是标准C的GNU添加。可能在某些编译器中不可用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.