算术表达式上下文中的宏扩展?

Ras*_*yak 6 c c++

我在网站上看到了以下代码.我无法理解结果是如何形成的11,而不是2513.

为什么我在想,25因为SQ(5) 5*5

或者13因为

SQ(2) = 4;

SQ(3) = 9;

可能是最终的结果将是13 (9 + 4) 惊讶地看到结果为11.结果如何11

using namespace std;
#define SQ(a) (a*a)
int main()
{
    int ans = SQ(2 + 3);
    cout << ans << endl;
system("pause");
}
Run Code Online (Sandbox Code Playgroud)

NPE*_*NPE 19

预处理器在源代码上执行简单的文本替换.它对基础语言或其规则一无所知.

在您的示例中,SQ(2 + 3)展开到(2 + 3*2 + 3),计算结果为11.

一种更健壮的定义方式SQ是:

#define SQ(a) ((a)*(a))
Run Code Online (Sandbox Code Playgroud)

现在,SQ(2 + 3)将扩展到((2 + 3)*(2 + 3)),给予25.

虽然这个定义是一种改进,但它仍然不是防弹的.如果SQ()应用于具有副作用的表达式,则可能产生不希望的后果.例如:

  • 如果f()是一个向控制台输出内容并返回一个的函数int,SQ(f())则会导致输出被打印两次.
  • 如果iint变量,SQ(i++)则会导致未定义的行为.

有关宏的困难的更多示例,请参阅宏陷阱.

由于这些原因,通常优选使用函数而不是宏.

  • 更健壮的方法是使用一个函数. (3认同)

Gow*_*ham 6

#define扩展在编译器看到源代码之前启动.这就是为什么它们被称为预处理器指令,这里的处理器是将C转换为机器可读代码的编译器.

所以,这就是宏预处理器传递给编译器的原因:

SQ(2 + 3) 被扩大为 (2 + 3*2 + 3)

所以,这真的是2 + 6 + 3= 11.

你怎么能让它做你期望的?

  1. 强制执行评估顺序.在宏定义或宏调用中使用().要么
  2. 写一个简单的功能来完成这项工作