zoukankan      html  css  js  c++  java
  • min宏的学习

    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
    ",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
    ",c);
  • 相关阅读:
    jQuery实现仿微博发布框字数提示
    jQuery实现滚动公告练习
    jQuery实现页面搜索
    jQuery某网站品牌列表效果
    [转]windows中断与共享的连接(samba)
    rpm --rebuilddb
    【转】一个 Linux 上分析死锁的简单方法
    取消脚本进程之——后台进程
    whoami与who am i
    linux启动执行某个脚本
  • 原文地址:https://www.cnblogs.com/litifeng/p/7691837.html
Copyright © 2011-2022 走看看