以总和作为参数的预处理器操作

Preprocessor operation with sum as parameter

是的,所以我正在尝试了解 C 预处理器,但伙计,这是一个忙碌的过程。

我有一个简单的

#define Square(x)(x*x) 

我需要在打电话时找出 Square(5+2) returns 的内容。作为这方面的新手,我立即想到它会显示 49,但是你看它返回 17。在接下来的好几分钟里,我试图找出这到底是怎么回事。

谁能给我解释一下?越全面越好,我比较笨

C 中的预处理器宏进行直接符号替换。所以这个:

Square(5+2)

变成这样:

(5+2*5+2)

While 被评估为:

(5+(2*5)+2)

也就是 17。

您应该始终将宏参数括起来以防止出现如下问题:

#define Square(x) ((x)*(x)) 

那么上面的调用将扩展为:

((5+2)*(5+2))

虽然已经 dbush explained correct ,但有一个更安全的选择:内联函数:

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

总是 无法将宏转换为内联函数(例如,对于日志记录,如果您想使用 __FILE____LINE__ 宏) ,或者它是,但你必须定义多个不同的版本(一个用于 int,一个用于 double,...),所以内联函数也不是圣杯,但随着参数被评估 before 函数被输入,你可以避免你犯的错误类型,此外,你无法对参数进行多次评估(有时甚至会导致未定义的行为:

int x = 7;
// inline function:
int y = square(x++); // safe
// macro:
int z = Square(x++); // expands to z = (x++)*(x++) which is undefined behaviour!

因此,如果您可以在没有不合理的代码开销的情况下使用内联函数,则更喜欢它们...