这个 C 代码的输出是 49 但有人能解释一下吗?

The output of this C code is 49 but can someone explain me how?

#include <stdio.h>

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

int main() {
    printf("%d", CUBE(4+5));
    return 0;
}

阅读 Modern C, then the n1570 draft C standard, and the documentation of GCC and of GDB and of CPP. See also this C reference 网站。

从现有的开源项目中汲取灵感,例如在 github, or GNU software.

最近 GCC compiler, invoke itgcc -Wall -Wextra -g。还可以使用 -C -E 选项来获取预处理的表单。

您可能还对 GCC 的 statement-expr 扩展感兴趣。

您的 CUBE(4+5) 被宏扩展为 4+5*4+5*4+5,根据 C operators.

的优先级计算为 4+(5*4)+(5*4)+5

考虑编写一个 static inline 函数,例如

static inline int cube(int x) { return x*x*x; }

或者如果你需要一个宏,至少

#define CUBE(X) ((X)*(X)*(X))

这对 CUBE(i++) 不太适用(使用 inline 函数时,cube(i++) 会执行您希望它执行的操作:递增 i 一次!) .

顺便说一句,你可以使用 GPP, or GNU m4, (or your own generator, or GNU bison) to generate some C code. As a rule of thumb, think with ASTs: when you generate C code, emit a lot of useless parenthesis, like e.g. in Chicken Scheme, SWIG, or in CAIA or in my manydl.c

您也可以使用 Clang static analyzer on your code (and maybe Frama-C).

您可能有兴趣阅读一些编码指南,例如 MISRA C or GNU ones

如果你想添加数字然后发送到 CUBE,你需要像 CUBE((4+5)) 这样的输入。因为 CUBE(4+5) 基本上扩展为 4+5*4+5*4+5,因为它将整个 4+5 设置为 x。所以,4+5*4+5*4+5 = 4+20+20+5 因为先乘法然后加上它们会得到 49.

#define CUBE(x) ((x)*(x)*(x))一样定义宏,它实际上首先对每个(x)执行(4+5)操作,然后执行*操作。

另一种方法是在调用宏时使用 CUBE((4+5)),它基本上是先将两个数字和 (4+5) = 9 相加,然后再执行 CUBE(9),例如:

#include<stdio.h>
#define CUBE(x) (x * x * x)

int main( )
{
    printf("%d", CUBE((4+5)));
    return 0;
}

宏会将代码变为:

printf("%d", (4+5 * 4+5 * 4+5));

这实际上是:

printf("%d", 4 + (5*4) + (5*4) + 5); // 29

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

C 预处理器将按字面意思用 x 的所有实例替换 4+5,从而产生以下代码:

i = 4+5*4+5*4+5;

(先乘后加)

下面是宏在编译过程中是如何扩展的:

printf("%d", (4+5 * 4+5 * 4+5));

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

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

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

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

,这就是一个问题

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

int cube(int x) {
    return x * x * x;
}

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