用C语言定义宏

用C语言定义宏,c,macros,C,Macros,假设我定义了一个宏: #define MAX(x,y) ((x)>(y)?(x):(y)) 如果我调用MAX(I++,J++),会发生什么 我不明白为什么答案不符合预期。宏只用于预处理器。这是C编译器将编译的内容: (((I++)>(J++))? ((I++):(J++))) 正如你所看到的,如果I大于J,那么我将得到两次和一次的增量,否则反之亦然 您的宏甚至不正确。此处括号的外层错误,这将导致编译错误: ((I++):(J++)) MAX(I++,J++)将扩展到((

假设我定义了一个宏:

#define MAX(x,y)    ((x)>(y)?(x):(y))
如果我调用
MAX(I++,J++)
,会发生什么


我不明白为什么答案不符合预期。

宏只用于预处理器。这是C编译器将编译的内容:

(((I++)>(J++))? ((I++):(J++)))
正如你所看到的,如果I大于J,那么我将得到两次和一次的增量,否则反之亦然


您的宏甚至不正确。此处括号的外层错误,这将导致编译错误:

((I++):(J++))
MAX(I++,J++)
将扩展到
((I++)>(J++)?((I++):(J++)
。请注意,
I++
J++
出现了两次,因此它们在比较后都会递增,然后,无论结果是什么,都会再次递增

您可以改用内联函数:

inline int MAX(int x, int y)
{
    return x > y ? x : y;
}
但我认为宏有适用于任何类型的优点。

in
int res=MAX(x,y)宏将扩展到

(((x) > (y)) ? (x):(y));
现在如果
x=a++
y=b++
,这将转换为

(((a++) > (b++)) ? (res = a++):(res = b++));
因此,对于条件为真的路径,无论它是哪个变量,都将总共inc两次,但存储在
res
中的结果值将只有一个增量(正如您使用的是后期增量)

在函数/宏调用中使用post inc可能很棘手,因为它们可能会引入微妙的逻辑故障


更喜欢将变量按原样传递给函数/宏,并单独对其进行任何更改,这将节省您处理此类问题的时间。

您得到了什么答案?你期望得到什么样的答案?正如我所说的,我认为宏具有适用于任何类型的优点(而每个类型都需要一个不同的函数)。值得一提的是:它是定义的行为,因为在计算左操作数(布尔编码)后有序列点。这在宏中并不常见,例如:
MAX(I++,I++)
将导致未定义的行为,因为
I
在同一表达式中增加了两次。