C语言中的MIN和MAX定义在哪里?

实现这些最好的方法是什么,尽可能的泛型和类型安全?(主流编译器的编译器扩展/内置优先。)


当前回答

值得指出的是,如果你用三元运算来定义最小值和最大值,比如

#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))

然后,为了在fmin(-0.0,0.0)和fmax(-0.0,0.0)的特殊情况下获得相同的结果,您需要交换参数

fmax(a,b) = MAX(a,b)
fmin(a,b) = MIN(b,a)

其他回答

它也在GNU libc (Linux)和FreeBSD版本的sys/param.h中提供,并具有dreamlax提供的定义。


在Debian上:

$ uname -sr
Linux 2.6.11

$ cat /etc/debian_version
5.0.2

$ egrep 'MIN\(|MAX\(' /usr/include/sys/param.h
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))

$ head -n 2 /usr/include/sys/param.h | grep GNU
This file is part of the GNU C Library.

在FreeBSD上:

$ uname -sr
FreeBSD 5.5-STABLE

$ egrep 'MIN\(|MAX\(' /usr/include/sys/param.h
#define MIN(a,b) (((a)<(b))?(a):(b))
#define MAX(a,b) (((a)>(b))?(a):(b))

源存储库在这里:

GNU C库 FreeBSD

旧的GCC扩展:操作符<?, > ?, < ?=, > ?=

在非常旧的GCC版本中,有操作符<?, > ?(看这里,它是在c++中,但我认为它当时也适用于C扩展) 我还见过操作符<?=, > ?=对应于赋值语句。

操作数只计算一次,甚至允许使用非常短的赋值语句。与常见的最小/最大赋值相比,它非常短。没有什么比这更好的了。

这些是以下内容的简写:

min(a, b)   ===   a < b ? a : b   ===   a <? b;
max(a, b)   ===   a > b ? a : b   ===   a >? b;
a = min(a, b);   ===   if(b < a) a = b;   ===   a <?= b;
a = max(a, b);   ===   if(b > a) a = b;   ===   a >?= b;

求最小值非常简洁:

int find_min(const int* ints, int num_ints)
{
    assert(num_ints > 0);
    int min = ints[0];
    for(int i = 1; i < num_ints; ++i)
        min <?= ints[i];
    return min;
}

我希望有一天GCC会用到这些运算符,因为我认为这些运算符很有天赋。

C语言中的MIN和MAX定义在哪里?

他们不是。

实现这些的最好方法是什么,尽可能的泛型和类型安全(主流编译器的编译器扩展/内置首选)。

作为功能。我不会使用像#define MIN(X, Y) (((X) < (Y))这样的宏?(X):(Y)),特别是如果您计划部署您的代码。要么写你自己的,使用标准的fmax或fmin,或者在GCC语句表达式中使用GCC的typeof(你也会得到类型安全奖励)修复宏:

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

每个人都说“哦,我知道双重求值,这没问题”,几个月后,你会连续几个小时调试最愚蠢的问题。

注意使用__typeof__而不是typeof:

如果你正在写一个头文件 必须工作时,包括在ISO C 程序,写__typeof__而不是 typeof。

我编写的这个版本适用于MSVC、GCC、C和c++。

#if defined(__cplusplus) && !defined(__GNUC__)
#   include <algorithm>
#   define MIN std::min
#   define MAX std::max
//#   define TMIN(T, a, b) std::min<T>(a, b)
//#   define TMAX(T, a, b) std::max<T>(a, b)
#else
#       define _CHOOSE2(binoper, lexpr, lvar, rexpr, rvar) \
                ({ \
                        decltype(lexpr) lvar = (lexpr); \
                        decltype(rexpr) rvar = (rexpr); \
                        lvar binoper rvar ? lvar : rvar; \
                })
#       define _CHOOSE_VAR2(prefix, unique) prefix##unique
#       define _CHOOSE_VAR(prefix, unique) _CHOOSE_VAR2(prefix, unique)
#       define _CHOOSE(binoper, lexpr, rexpr) \
                _CHOOSE2( \
                        binoper, \
                        lexpr, _CHOOSE_VAR(_left, __COUNTER__), \
                        rexpr, _CHOOSE_VAR(_right, __COUNTER__) \
                )
#       define MIN(a, b) _CHOOSE(<, a, b)
#       define MAX(a, b) _CHOOSE(>, a, b)
#endif

如果你需要min/max来避免昂贵的分支,你不应该使用三元运算符,因为它会编译成一个跳转。下面的链接描述了实现最小/最大函数而不进行分支的有用方法。

http://graphics.stanford.edu/~seander/bithacks.html#IntegerMinOrMax