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=,b=;
int c=min(a,b);
printf("c=%d\n",c); return ;
}

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

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

int main(int argc, char *argv[])
{
int a=,b=;
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宏的学习的更多相关文章

  1. $Min\_25$筛学习笔记

    \(Min\_25\)筛学习笔记 这种神仙东西不写点东西一下就忘了QAQ 资料和代码出处 资料2 资料3 打死我也不承认参考了yyb的 \(Min\_25\)筛可以干嘛?下文中未特殊说明\(P\)均指 ...

  2. cocos2d-x-3.1 经常使用宏 (coco2d-x 学习笔记五)

    在代码中使用这些宏,能够降低敲键盘的次数,从而提高编写效率. 与节点属性(property)相关的 CC_PROPERTY_READONLY CC_PROPERTY_READONLY_PASS_BY_ ...

  3. ios宏定义学习

    宏简介: 宏是一种批量处理的称谓.一般说来,宏是一种规则或模式,或称语法替换 ,用于说明某一特定输入(通常是字符串)如何根据预定义的规则转换成对应的输出(通常也是字符串).这种替换在预编译时进行,称作 ...

  4. iOS开发笔记--宏定义的黑魔法 - 宏菜鸟起飞手册

    宏定义在C系开发中可以说占有举足轻重的作用.底层框架自不必说,为了编译优化和方便,以及跨平台能力,宏被大量使用,可以说底层开发离开define将寸步难行.而在更高层级进行开发时,我们会将更多的重心放在 ...

  5. iOS 7:漫谈#define 宏定义

           #define宏定义在C系开发中可以说占有举足轻重的作用.底层框架自不必说,为了编译优化和方便,以及跨平台能力,宏被大量使用,可以说底层开发离开define将寸步难行.而在更高层级进行开 ...

  6. iOS 7:漫谈#define 宏定义(转)

    iOS :漫谈#define 宏定义 #define宏定义在C系开发中可以说占有举足轻重的作用.底层框架自不必说,为了编译优化和方便,以及跨平台能力,宏被大量使用,可以说底层开发离开define将寸步 ...

  7. opencv编程解决warning C4003: “max”宏的实参不足

    忘了把程序出错的代码附上了,运行修改好的程序才发现的.只好把问题的代码大致写一下了: warning C4003: “min”宏的实参不足 error C2589: “(”:“::”右边的非法标记 e ...

  8. not enough actual parameters for macro 'min'(QT与vs2010)

    解决方案见以下: qdatetime.h:“min”宏的实参不足 | 浏览:73 | 更新:2015-01-06 12:36 百度经验:jingyan.baidu.com 最近用VS2012 中Qt5 ...

  9. 宏和函数的区别(一个BUG的总结)

    [1]BUG简单示例代码 主要代码如下: #include <QCoreApplication> #include <QDebug> #define ADD(a, b, c) ...

随机推荐

  1. List of Chromium Command Line Switches(命令行开关集)——官方指定命令行更新网址

    转自:http://peter.sh/experiments/chromium-command-line-switches/ There are lots of command lines which ...

  2. 用百度SDK获取地理位置和天气信息

    以下实现通过百度SDK获取地理位置和天气信息,请參考title=android-locsdk/guide/v5-0">百度开发文档 1. 在相关下载最新的库文件.将so文件的压缩文件解 ...

  3. 如何利用Flink实现超大规模用户行为分析

    如何利用Flink实现超大规模用户行为分析   各位晚上好,首先感谢大家参与我的这次主题分享,同时也感谢 InfoQ AI 前线组织这次瀚思科技主题月! 瀚思科技成立于 2014 年,按行业划分我们是 ...

  4. 14.ThreadLocal

    ThreadLocal     1.线程局部变量,是一种多线程并发访问变量的解决方案,与同步技术 synchronize 加锁的方式不同,threadlocal完全不提供锁,而使用        空间 ...

  5. 数学图形(1.39)TN constant curve

    这是个类似巴黎铁塔的曲线. #http://www.mathcurve.com/courbes2d/tn/tn.shtml vertices = t = to (PI*0.999) a = s = s ...

  6. ActiveMQ的环境搭建及使用

    一:环境搭建 ActiveMQ官网下载mq在windows上的安装包:http://activemq.apache.org/,解压到某个磁盘下. 运行要环境条件:jdk安装1.8,(本人这里安装版本) ...

  7. GCD的基本概念

    GCD是苹果在OS X Snow Leopard跟iOS4后引入的一个技术,利用GCD,我们可以将多线程代码编写的很优雅.在使用GCD前,我们可以简章回顾下传统的多线程技术. int main() { ...

  8. 使用SQL SERVER FOR XML PATH将多个结果集转换成一行并进行去重处理

    在一个医药行业的系统中需要根据患者的接触记录ID获取不同接触类型的集合,效果像这样     --患者接触记录信息,一个患者可以有N个不同的接触记录,每个接触记录又有N个接触类型记录 IF OBJECT ...

  9. 文件同步程序,Python和C写的DLL

    #coding:utf-8 from ctypes import * from FileCopy import * def GetFilePathList(FilePath): dll = CDLL( ...

  10. C# 实现对微博短网址的重定向还原

    新浪微博中,为了节省输入字数,通过短网址对发布微博中链接进行重定向.我们可以通过代码实现对短网址进行还原,代码如下: private string GetOrignalLink(string link ...