假设我定义了一个宏:
#define MAX(x,y) ((x)>(y)?(x):(y))
如果我打电话会发生什么MAX(I++,J++)
?
我不明白为什么答案不会像预期的那样。
宏仅用于预处理器。这是由 C 编译器编译的内容:
(((I++)>(J++))? ((I++):(J++)))
如您所见,如果 I 大于 J,那么我将增加两次,而 J 增加一次,反之亦然。
你的宏甚至不正确。此处括号外层错误,会导致编译错误:
((I++):(J++))
MAX(I++,J++)
会扩大到(((I++)>(J++))? ((I++):(J++)))
. I++
请注意, and出现了两次J++
,所以它们都会在比较之后递增,然后无论结果是哪个,都会再次递增。
您可以改用内联函数:
inline int MAX(int x, int y)
{
return x > y ? x : y;
}
但我认为宏具有适用于任何类型的优势。
在int res = MAX(x,y);
宏中将花费到
(((x) > (y)) ? (x):(y));
现在如果x = a++
和y = b++
那将转化为
(((a++) > (b++)) ? (res = a++):(res = b++));
因此,对于条件为真的路径,无论它是哪个变量,总共将是两次 inc,但存储的结果值res
将只有一个增量(因为您使用的是后增量)。
在函数/宏调用中使用 post-inc 可能会很棘手,因为它们会引入微妙的逻辑故障。
更喜欢将变量按原样传递给函数/宏,并单独对其进行任何更改,这将节省您处理此类问题的时间。