码迷,mamicode.com
首页 > 其他好文 > 详细

min宏的学习

时间:2017-10-19 13:54:46      阅读:171      评论:0      收藏:0      [点我收藏+]

标签:匹配   c语言   class   标识符   ==   size   line   数值   back   

1、先上实现代码:

#define __min(t1, t2, min1, min2, x, y) ({      \
    t1 min1 = (x);                      t2 min2 = (y);                      (void) (&min1 == &min2);                min1 < min2 ? min1 : min2; })
#define min(x, y)                   \
    __min(typeof(x), typeof(y),                   __UNIQUE_ID(min1_), __UNIQUE_ID(min2_),             x, y)

__UNIQUE_ID(min1_)含义是制造一个唯一的标识符:__UNIQUE_ID_min1_0

__UNIQUE_ID(min2_)含义是制造一个唯一的标识符:__UNIQUE_ID_min2_1

2、为什么把x,y赋值给_min1和_min2然后返回_min1和_min2,而不直接写成(x) < (y)? (x) :(y)呢?这个就是最经典的C语言课本中所说的那个所谓的++的问题了,假如我写成min(a++,b++),展开成宏就变成了(a++) < (b++)? (a++) :(b++)了,究竟a和b各自++了多次,所以我们一定要先把它们赋值给两个局部变量,这样就没有这个问题了。

3、 (void) (&min1 == &min2); 这一行有啥用?检查两个数类型是否匹配,不匹配编译器会报错的,注意必须是地址之间的判等才是类型比较,如果是值的话,那就是单纯的比较数值了和类型就无关了,所以这里要转换成地址,

      另外再将结果强转为void,也是加强说明这是一个类型比较,不可以用作右值,通过void显式丢弃一个表达式的值,否则有些编译器会就此给出警告信息)。(void) (&_x == &_y); 中的void,表示将表达式(&_x == &_y); 所得到的结果( 如果是逻辑上的假,值为0)忽略掉。如果不加void,则会提示你这行代码是无意义的,没人用到,有些编译器会产生警告信息

4、为了便于研究,我把涉及到的宏全部提炼出来,写了一个测试程序:

#include <stdio.h>                                                                                 
#define ___PASTE(a,b) a##b
#define __PASTE(a,b) ___PASTE(a,b)
#define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __COUNTER__)
#define __min(t1, t2, min1, min2, x, y) ({      \
        t1 min1 = (x);                          t2 min2 = (y);                          (void) (&min1 == &min2);                    min1 < min2 ? min1 : min2; })
#define min(x, y)                   \
    __min(typeof(x), typeof(y),                     __UNIQUE_ID(min1_), __UNIQUE_ID(min2_),               x, y)


int main(int argc, char *argv[])
{
    int a=10,b=20;
    int c=min(a,b);
    printf("c=%d\n",c);

    return 0;
}

5、__COUNTER__是GCC内置的一个累加器,每次调用都会在以前的基础上加1,从0开始计数。

6、这是解开宏后的源码:

int main(int argc, char *argv[])
{
 int a=10,b=20;
 int c=({ typeof(a) __UNIQUE_ID_min1_0 = (a); typeof(b) __UNIQUE_ID_min2_1 = (b); (void) (&__UNIQUE_ID_min1_0 == &__UNIQUE_ID_min2_1); __UNIQUE_ID_min1_0 < __UNIQUE_ID_min2_1 ? __UNIQUE_ID_min1_0 : __UNIQUE_ID_min2_1; });
 printf("c=%d\n",c);

 

min宏的学习

标签:匹配   c语言   class   标识符   ==   size   line   数值   back   

原文地址:http://www.cnblogs.com/litifeng/p/7691837.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!