C++ 中的 MAX 和 MIN 宏

Sep 18, 2022 • 预计阅读时间 1 分钟

在学习 C 语言的时候,最先接触到的两个宏 MAXMIN,用于找出两个数中较大和较小的那个值。

大多数的教程中,这两个宏的定义是这样的:

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

ab 可以是变量或者常量,也可以是表达式或者函数调用

因为宏的本质是字符替换,当宏展开以后 a 或者 b 就会出现两次,也就是说如果 a 或者 b 是表达式或者函数的情况下, 就会被执行两次,可能会导致得不到预期的结果,一个简单的例子:

int a = 2, b = 1;
MAX(a++, b); // a++ 这个表达式在宏展开后,会调用两次
// a 的值变成 4

要解决这个问题也很简单,就是把 ab 的结果保存起来再进行比较,在 clang 中 MAXMIN 的宏定义是这样的:

#define __NSX_PASTE__(A,B) A##B

#if !defined(MIN)
    #define __NSMIN_IMPL__(A,B,L) ({ __typeof__(A) __NSX_PASTE__(__a,L) = (A); __typeof__(B) __NSX_PASTE__(__b,L) = (B); (__NSX_PASTE__(__a,L) < __NSX_PASTE__(__b,L)) ? __NSX_PASTE__(__a,L) : __NSX_PASTE__(__b,L); })
    #define MIN(A,B) __NSMIN_IMPL__(A,B,__COUNTER__)
#endif

#if !defined(MAX)
    #define __NSMAX_IMPL__(A,B,L) ({ __typeof__(A) __NSX_PASTE__(__a,L) = (A); __typeof__(B) __NSX_PASTE__(__b,L) = (B); (__NSX_PASTE__(__a,L) < __NSX_PASTE__(__b,L)) ? __NSX_PASTE__(__b,L) : __NSX_PASTE__(__a,L); })
    #define MAX(A,B) __NSMAX_IMPL__(A,B,__COUNTER__)
#endif

定义两个局部变量保存 ab 的结果,然后再进行比较。

这个宏定义在 C 语言中已经完美了。

在 C++ 中,这两个宏还存在一点瑕疵,就是比较的时候 ab 的结果可能不是同一种数据类型,所以在 C++ 中使用模板函数 std::minstd::max 来替代 MINMAX,这两个模板函数包含在头文件 <algorithm> 中。

C++
版权声明:如果转发请带上本文链接和注明来源。

lvv.me

iOS/macOS Developer

Windows 11 22H2 安装时跳过网络连接

ObjC++ 中的 lambda 和 block