在写C/C++语言时我们经常会用到宏定义,宏函数就是带参数的宏定义(blablabla……省去背景介绍)。

有时候我们会需要一个可以有多种参数版本的宏定义,例如:

1
2

#define MACRO_FUN(a) doSomethingWithOneArg(a)
#define MACRO_FUN(a, b) doSomethingWithTwoArgs(a, b)

但是宏定义不像正规函数那样可以重载,一旦试图重复定义一个已经定义的宏,就会把之前的定义覆盖掉。那么怎么正确的重载宏函数呢?

首先需要了解可变参数宏__VA_ARGS__,__VA_ARGS__可以将宏中的参数…展开,例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14

#define F(...) f(__VA_ARGS__)
#include <cstdio>
int f ( int a , int b , int c )
{
return a + b + c ;
}
int main ( void )
{
printf ( "%d" , F ( 1 , 2 , 3 ) ) ; // outputs 6
return 0 ;
}

现在,见证奇迹的时候到了,以重载可以有一个或者两个参数的宏函数为例:

1
2
3
4
5
6
7
8
9

#define OneArgument(a) // ...action with one argument
#define TwoArguments(a, b) // ...action with two arguments
#define GetMacro(_1, _2, NAME, ...) NAME
#define Macro(...) GetMacro(__VA_ARGS__, TwoArguments, OneArgument, ...)(__VA_ARGS__)
// usage:
Macro ( a ) ; // OneArument(a) is called
Macro ( a , b ) ;    // TwoArguments(a, b) is called

tada!是不是没有反应过来这有什么用呢?我们来测试一下这个宏定义是如何工作的,首先来看一个参数的情况:

Macro(a)=>GetMacro(a, TwoArguments, OneArgument)=>OneArgument(a)

两个参数的情况:

Macro(a, b)=>GetMacro(a, b, TwoArguments, OneArgument)=>TwoArgument(a, b)

很巧妙的实现了宏函数的重载功能,那么怎么实现三个参数的重载呢,同理:

1
2
3
4
5
6
7
8
9
10
11

#define OneArgument(a) // ...action with one argument
#define TwoArguments(a, b) // ...action with two arguments
#define ThreeArguments(a, b, c) // ...action with three arguments
#define GetMacro(_1, _2, _3, NAME, ...) NAME
#define Macro(...) GetMacro(__VA_ARGS__, ThreeArguments, TwoArguments, OneArgument, ...)(__VA_ARGS__)
// usage:
Macro ( a ) ; // OneArument(a) is called
Macro ( a , b ) ;    // TwoArguments(a, b) is called
Macro ( a , b , c ) ;    // ThreeArguments(a, b, c) is called

博客源地址:http://blog.nemoge.com/trick-for-overload-macro-function-in-c/

C语言重载宏函数的小技巧相关推荐

  1. C语言基础--宏函数

    C语言基础–宏函数 1. 函数和数据类型 函数式宏(宏函数)和函数类比会更加灵活,我们通过两个例子来看一下. 函数 #include <stdio.h> int sqr_int(int x ...

  2. excel的if函数中android,excel中if函数使用小技巧分享

    excel中if函数使用小技巧分享[案例实操] 今天有同事问到笔者一个问题:"在EXCEL中,如何使用函数实现如下功能:在A1单元格填写A,B1单元格自动填写100,当A1单元格的内容更改为 ...

  3. C语言_宏函数_换行符

    在写代码时,发现很多代码重复,为了缩减代码及利于代码维护,将重复的代码通过宏函数的方式进行定义. 简单地将重复代码拷贝出来,通过宏定义封装了一下:因为多行代码,通过换行符进行了规范.使用了宏函数之后发 ...

  4. mysql main函数_关于main()函数的小技巧

    话说,有这样一道据说是月薪2W的笔试题: #include stdio.h void print() { * } void main() { } 要求在*部分写代码使整个程序运行后输出"he ...

  5. C语言 用宏函数实现 swap() 交换函数

    函数功能: 交换任意两个同类型的数 函数一: #include <stdio.h> /** 运行环境:MinGW 和 MSVC 都可用* *//** 这里添加 do-while 循环是为了 ...

  6. edpluse怎么运行c语言,使用EditPlus的一些小技巧

    使用 EditPlus进行Java程序的编写,首先是环境的配置,这样不用反复的进行CMD的操作.本文先演示了在CMD系进行java程序的编译和执行过程,接着进行了EditPlus的环境配置.当然使用N ...

  7. C语言--visual studio 2019使用小技巧(番茄助手的代码提示)

    visual studio 2019的快捷键使用这里就不讲了,网上一搜一大堆.这里讲一下如何快速写整块的代码,省得我们在测试小案例的时候写那些重复的代码,比如#include <stdio.h& ...

  8. excel函数使用小技巧对角线元素

    1.对角线元素提取 方案一 以A1:E5所在的方形区域为例: 在G1:G5各单元输入公式"=OFFSET($A$1,ROW()-1,ROW()-1)",即可将对角线上的数字变成一列 ...

  9. Matlab中dir函数使用小技巧

    想必很多小伙伴在matlab中对文件进行批处理时经常会使用dir函数吧,dir函数用于列出文件夹中的内容.使用语法如下: % Matlabdir % 列出当前文件夹中的文件和文件夹,当然调用方式也可以 ...

最新文章

  1. 吴恩达 coursera AI 第四课总结+作业答案
  2. 无法连接 MKS: Login(username/password)incorrect
  3. javaScript入门基础说明
  4. mysql current_MySQL中CURRENT_TIMESTAMP数据类型详解
  5. c语言程序设计实验周信东指针,C语言程序设计实验4 数组 周信东
  6. 多主机远程桌面连接,系统自带的。tsmmc
  7. Win7 连接局域网共享之后 提示错误代码:0x800704b3(实测可用)
  8. java开发 网关_SpringCloud系列之网关(Gateway)应用篇
  9. 【WC2013】糖果公园
  10. visa虚拟卡生成器_你们要的电子虚拟信用卡,它来了,准备好盘了吗?
  11. 深度deepin安装腾达U12无线网卡驱动
  12. Java实现对List集合去重的几种方法
  13. Qt: 读取/写入文本文件内容
  14. 你知道甲醛的危害有多大吗?
  15. C语言——函数的声明
  16. 后AlphaFold时代的蛋白质结构预测
  17. MCU 微控制器,在实际项目中如何选型(以 STM32为例)
  18. eclipse怎么把图片打开
  19. 如何推广你的联盟计划:10种行之有效的营销方式
  20. SSM框架实例——在线考试系统

热门文章

  1. 金融事业部QA培训体系
  2. Python中Set函数
  3. 如何生成tfrecord
  4. 新闻列表 android,- Android中实现简单的新闻列表
  5. sed命令详解及运用
  6. 金蝶EAS BOS开发固定报表流程
  7. 0x01-medium_socnet
  8. [ 后端篇 ] 10 - AWS API 返回 Endpoint request time out
  9. 云米科技的未来,谈不上乐观
  10. PTA-输出大写英文字母