我试过这个宏:
#define min(x,y) x<y? x:y
它应该返回最小值而它确实返回。唯一的问题是当尝试在操作中使用该宏的结果时,它不起作用。
实施例
x=min(3,4);
这里x自然会有3作为值,但在尝试时:
x= 23 + min(3,4);
结果仍然总是3(宏的结果),无论我添加多少数字(23都是任意的)。 我可以知道为什么会这样吗?
答案 0 :(得分:2)
min
应定义为:
#define min(a,b) (((a) < (b)) ? (a) : (b))
您似乎也在混合MIN
和min
。 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
这不是我们想要的。 y
或z
将增加两次。
答案 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) )
但是对这样的函数使用宏仍然是一个坏主意。参数的所有重复意味着您不能将其与具有副作用的表达一起使用。例如。 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分。