这个 C 代码的输出是 49 但有人可以解释我怎么做吗?

Aak*_*ati 1 c c-preprocessor

#include <stdio.h>

#define CUBE(x) (x * x * x)

int main() {
    printf("%d", CUBE(4+5));
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

chq*_*lie 9

以下是宏在编译过程中的展开方式:

printf("%d", (4+5 * 4+5 * 4+5));
Run Code Online (Sandbox Code Playgroud)

因为*具有比 更高的优先级+,所以这个表达式被计算为(4 + (5 * 4) + (5 * 4) + 5),产生49而不是预期的729

为避免此类运算符优先级问题,所有宏参数都必须在宏定义以及表达式本身中用括号括起来:

#define CUBE(x)  ((x) * (x) * (x))
Run Code Online (Sandbox Code Playgroud)

但是请注意,这种扩展会CUBE计算x多次,如果宏参数有副作用,例如CUBE(i++).

为了避免所有这些问题,请使用一个函数并让编译器对其进行优化:

int cube(int x) {
    return x * x * x;
}
Run Code Online (Sandbox Code Playgroud)

您可以static inline在此函数定义前添加,但现代优化器仍会在没有此内容的情况下内联该函数。


小智 5

宏会将代码变为:

printf("%d", (4+5 * 4+5 * 4+5));
Run Code Online (Sandbox Code Playgroud)

这是有效的:

printf("%d", 4 + (5*4) + (5*4) + 5); // 29
Run Code Online (Sandbox Code Playgroud)

如果你想立方体9得到729,你应该写CUBE((4+5))

  • 或者停止使用类似函数的宏。在当今优化编译器的世界中,只需将其编写为函数,如果好处足够,编译器将内联它(您甚至可以使用“inline”向编译器建议)。 (3认同)
  • 回复“如果你想要 729,你应该写 CUBE((4+5))”:不,宏应该用括号编写,这样用户就不必提供它们。 (3认同)
  • @Eric,覆盖*所有*情况的宏魔法量(例如“CUBE(x++)”)使得类似函数的宏成为一个非常糟糕的主意。最好放弃它们,使用宏进行简单定义,并使用内联建议的函数来处理其他所有内容。 (2认同)