【问题标题】:Defining Macro in C for MIN of 2 numbers [closed]在 C 中为 2 个数字的 MIN 定义宏 [关闭]
【发布时间】:2013-08-02 13:19:56
【问题描述】:

#define MIN (A,B) ((A)<(B)?(A):(B))#define MIN (A,B) ((A < B)? A : B )

请选择一个答案,为什么?!

【问题讨论】:

  • 请不要使用。不止一次评估参数的宏是危险的。现代 C 具有类型通用表达式,可以帮助为工作选择正确的内联函数。

标签: c macros c-preprocessor


【解决方案1】:

让我们有这个表达式:

int c = MIN(x == y, 1);

让我们试试#define MIN (A,B) ((A < B) ? A : B )

在 C 中,== 运算符的优先级低于<(所以x == y < z 等同于x == (y < z)),所以它会变成

int c = MIN (x == (y < 1) ? x == y : 1)

如果你使用第二种表达方式...而且是错误的,所以最好使用第一种形式。

让我们试试#define MIN (A,B) ((A) &lt; (B) ? (A) : (B)) 以确保...

我们来了

int c = MIN ((x == y) < (1) ? (x == y) : (1))

好多了!

最后他们都是“坏的”,因为

int c = MIN(++x, 1);

将对++x 进行两次评估(一次在&lt; 比较中,一次如果它被三元运算符“选择”作为结果)

int c = MIN ((++x) < (1) ? (++x) : (1))

【讨论】:

    【解决方案2】:

    就我个人而言,我不会使用任何一个,因为像 MIN(++a, ++b) 这样的表达式可能会让你搞砸(由于双重评估)。

    【讨论】:

    • 你能详细说明为什么这是一个问题。
    • 这是未定义的行为,如a++ &lt; b++ 是未定义的行为。
    • a++ ++a < ++b ? ++a : ++b
    • @IngoLeonhardt 和 @Eric Postpischil 你说得对,我对这种类型的表达式 a++ &lt; ++a 感到困惑,这最终确实会发生。
    • @Eric Postpischil 谢谢,我不知道
    【解决方案3】:

    我个人的偏好是:

    inline int min(int a, int b) 
    {
       return (a > b)?b:a;
    }
    

    这样更安全,不需要额外的括号,并且如果您执行以下操作也不会“爆炸”:

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

    【讨论】:

    • 实际上,有人会使用 min(x++, y++) 吗?即使例程正常工作,这似乎是一个非常糟糕的编码决定。
    • 是的,但你可能想做while(*ptr) lowest = min(*ptr++, lowest); 或类似的东西——如果它是一个宏,它的行为也会很奇怪。
    【解决方案4】:

    前者,因为 A 或 B 可以是嵌套命令。考虑这两个宏如何扩展它:

    int i = MIN(3+1,2);
    

    【讨论】:

    • 前者确实解决了嵌套问题,但仍然会因为重复评估而搞砸。考虑将int i = MIN(6, a++) 扩展为int a = 10
    猜你喜欢
    • 2011-11-18
    • 2022-01-19
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    • 2020-01-15
    • 1970-01-01
    相关资源
    最近更新 更多