#define 与运算符一起使用

#define used with operators

本文关键字:一起 运算符 #define      更新时间:2023-10-16

我知道#define有以下语法:#define SYMBOL string例如,如果我写

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

然后ALPHA = 1BETA = 0.(为什么?

但是如果我写这样的东西

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

然后ALPHA = 1BETA = 2.

有人可以解释一下这两者之间有什么区别吗?

使用#define创建的预处理器宏是文本替换。

这两个例子并不等同。 第一组BETA2-1*2。 第二组BETA(2-1)*2。 像你这样声称ALPHA == 1是不正确的,因为ALPHA不是一个数字——它是一个自由人!它只是一个字符序列。

当解析为 C 或 C++ 时,这两个表达式是不同的(第一个与2 - (1*2)相同(。

我们可以通过打印BETA的字符串扩展并将其作为表达式进行评估来显示差异:

#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 = %dn", str(BETA), BETA);
return 0;
}

在定义和未定义PARENS的情况下编译上述内容以查看差异:

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

这样做的结果是,当使用#define创建扩展到表达式的宏时,通常最好使用比通常需要的更多的括号,因为您不知道将在其中扩展值的上下文。 例如:

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

宏(#define ...(只是文本替换。

使用此版本:

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

预处理器将BETA替换为ALPHA*2然后ALPHA替换为2-1。宏扩展结束后,BETA将替换为2-1*2(由于运算符优先级(等于2-(1*2)=0

当您在">ALPHA的值"周围添加括号时(ALPHA实际上没有值,因为宏只是文本替换(,您将更改操作的计算顺序。现在BETA被等于 2 的(2-1)*2替换。

操作顺序。第一个示例变为 2-1*2,等于 2-2。 另一方面,第二个示例扩展到 (2-1(*2,计算结果为 1*2。

在第一个示例中:

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

alpha 将直接替换为您为其提供的任何值(在本例中为 2-1(。 这导致 BETA 扩展到(成为(2-1*2,其计算结果为 0,如上所述。

在第二个示例中:

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

Alpha(在 BETA 的定义范围内(扩展为设置为 (2-1( 的值,然后每当使用 BETA 时都会扩展到 (2-1(*2。

如果您在运算顺序方面遇到问题,您可以随时使用首字母缩略词PEMDAS来帮助您(括号指数乘法除法加法减法(,它本身可以记住为"请原谅我亲爱的萨莉阿姨"。首字母缩略词中的第一个运算必须始终在首字母缩略词中的后续运算之前完成(乘法和除法除外(在等式中,您只需从左到右,因为它们被认为具有相同的优先级,以及加法和减法(与乘法和除法相同的情况(。

C/C++ 中的宏只是文本替换,而不是函数。因此,宏的存在只是为了在编译器事件尝试分析代码之前将程序文本中的宏名称替换为其内容。因此,在第一种情况下,编译器将看到以下内容:

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

在第二个

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