在C中定义“between”宏的最佳方法

时间:2011-11-28 07:54:41

标签: c coding-style macros

定义宏之间的最佳方法是什么,类型泛型(char,int,long) 如果数字在输入的其他数字之间,则返回true。 我试图谷歌,但我没有找到任何东西。

编辑:给出的两个边界的顺序无关紧要。所以它可以更通用。

6 个答案:

答案 0 :(得分:4)

如果您执行以下操作:

#define BETWEEN(a, b, c)  (((a) >= (b)) && ((a) <= (c)))

你会对a的双重评估产生问题。想想如果你使用具有副作用的函数来做会发生什么......

你应该做类似的事情:

#define BETWEEN(a, b, c) ({ __typeof__ (a) __a = (a); ((__a) >= (b) && ((__a) <= (c)) })

(编辑因为结果不应该取决于b和c的顺序):

#define BETWEEN(a, b, c) \
           ({ __typeof__ (a) __a = (a);\
              __typeof__ (b) __b = (b);\
              __typeof__ (c) __c = (c);\
               (__a >= __b && __a <= __c)||\
               (__a >= __c && __a <= __b)})

答案 1 :(得分:3)

首先,不要将宏用于这样的事情 - 使用函数(可能是内联的)。

其次,如果必须使用宏,那么例如错误。

#define BETWEEN(x, x_min, x_max) ((x) > (x_min) && (x) < (x_max))

根据您的后续修改,如果您不知道x_minx_max的顺序,那么您可以这样做:

#define BETWEEN2(x, x0, x1) (BETWEEN((x), (x0), (x1)) || \
                             BETWEEN((x), (x1), (x0)))

关于宏和副作用等的常见警告适用。 编辑:删除宏与&之间的空格编译的参数

答案 2 :(得分:2)

如果所有类型都相同,那么:

/* Check if 'a' is between 'b' and 'c') */
#define BETWEEN(a, b, c)  (((a) >= (b)) && ((a) <= (c)))

请注意,如果上述abc的类型不同,则C的隐式类型转换可能会导致错误。特别是如果你混合有符号和无符号数字。

答案 3 :(得分:1)

如果我理解正确,你将需要3个数字,上限,下限和你正在检查的数字,所以我会这样做:

#define BETWEEN(up, low, n) ((n) <= (up) && (n) >= (low))

这假设介于两者之间,包括上限和下限,否则:

#define BETWEEN(up, low, n) ((n) < (up) && (n) > (low))

答案 4 :(得分:1)

+1:一个不那么重要的问题,因为它涉及宏观参数评估的问题。天真的解决方案是

#define BETWEEN(x,l1,l2) (((x) >= (l1)) && ((x) <= (l2)))

但“x”被评估两次,因此如果表达式有副作用可能会出现问题。让我们更聪明地尝试一下:

#define BETWEEN(x,l1,l2) (((unsigned long)((x)-(l1))) <= (l2))

非常非常棘手而且不那么干净,但是......

答案 5 :(得分:1)

#define BETWEEN_MIN(a, b) ((a)<(b) ? (a) : (b))
#define BETWEEN_MAX(a, b) ((a)>(b) ? (a) : (b))

#define BETWEEN_REAL(val, lo, hi) (((lo) <= (val)) && ((val) <= (hi)))
#define BETWEEN(val, hi, lo) \
      BETWEEN_REAL((val), BETWEEN_MIN((hi), (lo)), BETWEEN_MAX((hi), (lo)))

请参阅正在运行的代码:http://ideone.com/Hb1vP