操作中的宏观结果故障

时间:2016-01-15 23:19:13

标签: c macros

我试过这个宏:

#define min(x,y) x<y? x:y

它应该返回最小值而它确实返回。唯一的问题是当尝试在操作中使用该宏的结果时,它不起作用。

实施例

x=min(3,4);

这里x自然会有3作为值,但在尝试时:

x= 23 + min(3,4);

结果仍然总是3(宏的​​结果),无论我添加多少数字(23都是任意的)。 我可以知道为什么会这样吗?

4 个答案:

答案 0 :(得分:2)

min应定义为:

#define min(a,b)  (((a) < (b)) ? (a) : (b))

您似乎也在混合MINmin。 C区分大小写,因此min()可能会调用其他内容。

#define min(X,Y) X<Y? X:Y  // I changed MIN to lowercase here
x= 23 + min(3,4);

- &GT;将扩展为:

x = 23 + 3 < 4 ? 3 : 4;

与:

相同
x = (23 + 3) < 4 ? 3 : 4;

这就是为什么需要括号的原因:

x = 23 + ((3 < 4) ? 3 : 4);

为避免进一步出现问题,例如:min(x | b + 4 / 2, y && 0x01 + 3);,会在所有值周围添加括号:

(((a) < (b)) ? (a) : (b))

使用此类宏观时,应注意以下

int y = 1;
int z = 2;

x = min(y++, z++);

评估结果为:

x = ((y++ < z++) ? y++ : z++); // some parentheses omitted

这不是我们想要的。 yz将增加两次。

答案 1 :(得分:2)

问题在于操作员的关联性和优先级。展开宏时,它变为:

x = 23 + 3 < 4 ? 3 : 4;

被解释为:

x = (23 + 3) < 4 ? 3 : 4;

因为算术的优先级高于比较运算符。您应该将扩展包装在括号中以强制将其视为单个表达式。

#define min(x,y) (x<y? x:y)

您还应该在每个参数的使用周围添加括号,以防它们是具有优先级低于<的运算符的表达式。

#define min(x,y) ( (x) < (y) ? (x) : (y) )

DEMO

但是对这样的函数使用宏仍然是一个坏主意。参数的所有重复意味着您不能将其与具有副作用的表达一起使用。例如。 min(i++, j++)会将其中一个变量增加两次。最好使用内联函数。

答案 2 :(得分:1)

这是为什么宏中的括号很重要的一个很好的例子。

此:

x= 23 + min(3,4);

扩展到:

x= 23 + 3<4? 3:4;

使用隐式括号,与:

相同
x= ((23 + 3)<4)? 3:4;

评估为4。

如果您像这样定义宏:

#define min(x,y) ((x)<(y)?(x):(y))

然后你明白了:

x= 23 + ((3)<(4)?(3):(4));

三元评估为3,因此x被指定为26。

答案 3 :(得分:0)

这是因为+具有最高优先级,&lt;是下一个?优先级最低。所以,

23 + min(3,4)

扩展为

23 + 3 < 4 ? 3 : 4

所以,首先完成添加,然后你有:

26 < 4 ? 3 : 4 

然后关系运算符完成了,你有:

0 ? 3 : 4

所以,实际上你应该得到4分。