【问题标题】:find min(a,b,c) or max(a,b,c) with using #define macro preprocessor in c在 c 中使用 #define 宏预处理器查找 min(a,b,c) 或 max(a,b,c)
【发布时间】:2018-06-19 04:40:54
【问题描述】:

这是我在考试中提出的问题:“用 c 语言用宏编写 min(a,b,c) 的源代码。”

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

有没有更好的方法来解决 min/max(x,y,z) 问题?

【问题讨论】:

  • 是的 - 不使用宏。
  • 请注意,FP 号码使用NaN,这将不会返回min(1.0, NaN, NaN) 的预期答案

标签: c macros c-preprocessor preprocessor


【解决方案1】:

您的解决方案以及所有基于可移植宏的解决方案是应尽可能限制宏的使用的一个很好的理由。现在,我几乎只将它们用于条件编译。

在定义常量方面,最好使用枚举。

就类函数宏而言,您最好使用可以建议编译器内联的函数,或者仅仅依靠编译器来解决这个问题(它们通常很擅长)。


类函数宏不是一个好主意的原因是,作为简单的文本替换,序列:

#define mymax(a, b) (a) > (b) ? (a) : (b)
int x = mymax(y++, complexFunction());

实际上会评估y++ 和/或调用complexFunction() 不止一次,这是一个真正的函数不会做的事情。

只要您了解这些限制,请务必使用它们。我,我将依靠编译器为函数做正确的事情,这样我就不必过多担心 C 的阴暗角落:-)

【讨论】:

    【解决方案2】:

    是的。编写函数。

    int min2( int x, int y        ) { return x < y ? x : y; }
    int min3( int x, int y, int z ) { return min2( x, min2( y, z ) ); }
    

    如果你想要漂亮,你可以编写一些可变参数宏来根据参数的数量选择正确的函数。不过,这些都很难写。

    如果您希望坚持使用 only 宏,那么您的选择就不那么友好了。 Ajay B 的解决方案(根据评论修复)效果很好。

    GCC 支持一些 nice extensions 以消除重新评估问题:

    #define max(a,b) \
       ({ typeof (a) _a = (a); \
           typeof (b) _b = (b); \
         _a > _b ? _a : _b; })
    

    然后,您可以轻松编写任何您希望不受括号或重新评估恐惧影响的 n 元宏。

    #define max3(a,b,c) max(a,max(b,c))
    

    【讨论】:

    • 据我了解,编译器通常应该处理重新评估问题,除非变量被明确标记为volatile
    • 你被教错了。考虑:max( ++x, y )。 x 会发生什么?
    【解决方案3】:

    我认为您在问题中错过的关键点是“宏”而不是宏。如果您将其进一步分解如下,您可以简化很多 -

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

    这也更容易理解。

    【讨论】:

    • 典型的良好宏指南在每个参数用法周围使用()(min2(min2(a, b), (c))) --> (min2(min2((a), (b)), (c)))
    • @chux 是的,但是由于min2已经有括号,所以我没有将它添加到min。你可以看到我在c 周围添加了它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-08-01
    • 2011-05-30
    • 1970-01-01
    • 2015-06-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多