宏定义
无参数宏
#define 标识符(一般大写) 替换列表
如:
#define PI 3.14
带参宏
#define 标识符(参数1,参数2,…,参数n) //替换列表
如:
#define MAX(a,b) ((a)>(b)?(a):(b))
注意: 宏定义在使用时尽量使用括号括起。
带参宏和函数的区别
- 1.宏替换发生在预处理阶段,函数调用在程序运行期间
- 2.函数调用时会对参数类型进行严格的检查,宏替换发生在预处理阶段,对带参宏调用的参数不做检查(带参宏不安全)
- 3.函数需要为参数分配空间
- 4.函数在调用时需要为检查传参类型是否一致带参,为参数分配空间。相对而言宏运行速度更快
- 5.如果宏定义替换的代码较长则会影响代码长度,函数不会
宏定义高级用法
特殊符号#
在带参宏的前面加上#可以强制将该参数转化为字符串。
#include <stdio.h>
#define MY_PRINT(a) printf("%s\n", #a);
int main(int argc, char** argv[]){
MY_PRINT(1111);
MY_PRINT("1111");
return 0;
}
终端输出结果为:
1111
"1111"
特殊符号##
“##”是一种分个连接方式,它的作用是先分隔,然后再强制连接。
#include <stdio.h>
#define TYPE1(type1, type2) type1 type1##_to_##type2
#define TYPE2(type1, type2) type2 type2##_to_##type1
TYPE1(int, float)(float b){
return (int)b;
}
int main(int argc, char** argv[]){
printf("%d\n", int_to_float(0.01));
return 0;
}
终端输出结果为:0。
宏定义中的do{}while(0)
使用do{}while(0)将宏定义括起的原因:
(1)空的宏定义避免waring
(2)存在一个独立的block,可以用来进行变量定义,进行比较复杂的实现
(3)如果出现在判断语句过后的宏,可以保证作为一个整体来实现