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