define :-)
宏定义是C/C++系中的重要组成部分,一般在一些底层框架性代码中起着非常重要的作用,本文将以循序渐进的方式,对宏的使用进行一些总结。
基本使用
宏的基本规则
宏定义可以理解为简单地对于文本进行替换,宏的替换发生在预编译的阶段,编译器根据语义分析,将宏替换为原有的字符,这个过程称为宏的展开。也正因为宏是简单的进行文本替换,所以可能会发生许多意想不到的情况,在Effective C++中,其实作者并不建议我们滥用宏定义。
多行宏
在宏中,我们使用\
进行换行,一个多行宏如下所示,最后一行不加\
代表结束:
1 | #define SYSCALL(name) \ |
宏的分类
我们可以按照功能将宏进行分类,分为对象宏和函数宏两种,对象宏一般用于定义一些常数,例如:
1 |
这一句将M_PI
定义为了圆周率,那么程序在预编译过程中就会将M_PI
替换为魔数。
而函数宏,就是行为类似函数,可以接收参数的宏,当我们定义宏的时候在宏名字后加一对括号,就创建了函数宏:
1 |
|
上面这个函数宏接受两个参数,返回较小的那个值.当然这个宏函数存在非常大的问题,因为宏是文本替换,而这个宏非常粗糙 ,甚至不能进行下面的计算。
1 | int a = 2 * MIN(3, 4); |
为何要使用宏
宏的一些高级用法
拼接
通过##
可以实现对于宏的拼接过程,考虑下面这个场景,系统调用中,sys_重复出现
1 | extern int sys_chdir(void); |
这种情况下,可以定义如下宏
1 |
|
当我们要用到SYS_fork时,就可以写为SYSCALL(fork)
,起到了精简代码的作用