C宏至少有两个数字

Vai*_*orn 5 c minimum c-preprocessor

我想用#define创建一个简单的宏来返回两个数字中较小的一个.

我怎么能用C做这个?提出一些想法,看看你是否可以使它更加混淆.

GMa*_*ckG 12

典型:

#define min(a, b) (((a) < (b)) ? (a) : (b))
Run Code Online (Sandbox Code Playgroud)

请注意,这至少评估两次,这是最近一个问题中发生灾难的原因.

但是你为什么要混淆呢?


这个结果将结果存储在变量中,并且只评估每个参数一次.它基本上是一个穷人的内联函数+声明:

#define min(t, x, a, b) \
            t x; \
            { \
                t _this_is_a_unique_name_dont_use_it_plz_0_ = a; \
                t _this_is_a_unique_name_dont_use_it_plz_1_ = b; \
                x = _this_is_a_unique_name_dont_use_it_plz_0_ < \  
                    _this_is_a_unique_name_dont_use_it_plz_1_ ? \
                    _this_is_a_unique_name_dont_use_it_plz_0_ : \  
                    _this_is_a_unique_name_dont_use_it_plz_1_ ; \
            }
Run Code Online (Sandbox Code Playgroud)

使用它像:

min(int, x, 3, 4)
/* x is an int, equal to 3
  Just like doing:

  int x = min(3, 4);

  Without double evaluation.
*/
Run Code Online (Sandbox Code Playgroud)


Dav*_*d X 5

而且,仅仅为了它的地狱,一个GNU C的例子:

#define MAX(a,b) ({ \
    typeof(a) _a_temp_; \
    typeof(b) _b_temp_; \
    _a_temp_ = (a); \
    _b_temp_ = (b); \
    _a_temp_ = _a_temp_ < _b_temp_ ? _b_temp_ : _a_temp_; \
    })
Run Code Online (Sandbox Code Playgroud)

它没有被混淆,但我认为这适用于任何类型,在任何情况下,(几乎,见评论)任何参数等; 如果你能想到任何反例,请更正.


abe*_*nky -6

对于稍微混乱的情况,请尝试以下操作:

#define MIN(a,b)  ((((a)-(b))&0x80000000) >> 31)? (a) : (b)
Run Code Online (Sandbox Code Playgroud)

基本上,它将它们相减,并将符号位视为 1 或 0。如果减法结果为负数,则第一个参数较小。

  • 假设类型是32位。 (8认同)
  • 遗憾的是,即使对于 32 位整数,这实际上也不起作用,除非您认为 2147483647 小于 -1。 (2认同)
  • @GMan:-1 无疑小于 2147483647,两者都是整数,并且在任何足够宽的有符号类型中进行比较以表示它们两者(例如,32 位二进制补码整数)。无符号比较与该问题无关。 (2认同)