博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
min宏的学习
阅读量:6096 次
发布时间:2019-06-20

本文共 2057 字,大约阅读时间需要 6 分钟。

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 
#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);

 

转载地址:http://svgwa.baihongyu.com/

你可能感兴趣的文章
Android主线程、子线程通信(Thread+handler)
查看>>
gitlab配置邮箱
查看>>
Win10桌面奔溃怎么办?雨林木风Win10奔溃解决方法教程
查看>>
mysql Inoodb 内核
查看>>
Redis 基础
查看>>
UITextField的returnkey点击事件
查看>>
特殊字体引用
查看>>
owlcar 用法心得 自定义导航
查看>>
数据结构 学习笔记03——栈与队列
查看>>
DB2 OLAP函数的使用(转)
查看>>
数学之美系列二十 -- 自然语言处理的教父 马库斯
查看>>
Android实现自定义位置无标题Dialog
查看>>
面试总结
查看>>
Chrome浏览器播放HTML5音频没声音的解决方案
查看>>
easyui datagrid 行编辑功能
查看>>
类,对象与实例变量
查看>>
HDU 2818 (矢量并查集)
查看>>
【转】php字符串加密解密
查看>>
22. linux 常用命令
查看>>
ASP.Net 使用GridView模板删除一行的用法
查看>>