对,所以我试图理解C预处理器,但是这很麻烦。
我有一个简单的
#define Square(x)(x*x)
,我需要找出Square(5+2)
在调用时返回什么。作为该领域的新手,我立即想到它将显示49
,但是瞧瞧它随17
一起出现了。在一段美好的时光里,我试图找出这种情况如何发生。
有人可以向我解释吗?尽可能全面,因为我有点笨。
答案 0 :(得分:6)
C中的预处理器宏直接进行符号替换。所以这个:
Square(5+2)
变成这样:
(5+2*5+2)
评估为:
(5+(2*5)+2)
17岁。
您应始终在宏参数中加上括号,以防止出现此类问题:
#define Square(x) ((x)*(x))
然后上述调用将扩展为:
((5+2)*(5+2))
答案 1 :(得分:0)
虽然dbush已经解释了正确的parenthesising in macros,但还有一种更安全的选择:内联函数:
static inline int square(int x)
{
return x*x;
}
不可能总是将宏转换为内联函数(例如,用于记录,如果要使用__FILE__
和__LINE__
宏),或者,但是您必须定义多个不同的版本(一个用于int,一个用于double,...),所以内联函数也不是圣杯,而是因为在之前求值,所以输入了函数,您可以避免所犯的错误类型的影响,此外,还可以避免对参数进行多次求值(有时甚至会导致不确定的行为:
int x = 7;
// inline function:
int y = square(x++); // safe
// macro:
int z = Square(x++); // expands to z = (x++)*(x++) which is undefined behaviour!
因此,如果您可以拥有内联函数而又不会增加不合理的代码开销,请选择它们...