首先明确三种的使用方法
一.宏
宏是使用#define来实现的,主要用法是
- 函数替换----------#define dbgprint(format,...) printf (format, ##__VA_ARGS__)
- 定义常量----------#define NUM (123)//两种用法,普通常量,数组定义
- 定义参数宏-------#define max(a,b) (a>b?a:b)
- 条件编译
#define DEBUG_INFO
#define DEBUG_LEVEL (1)
#ifdef DEBUG_INFO
//具体调试信息输出代码
.....
#endif
#if(DEBUG_LEVEL > 1)
//分级调试信息输出代码
......
#endif
说明:
- 函数替换宏中的“__VA_ARGS__”是C99规范中可变参数宏的参数标识,用于表示前边的“...”,属于C99规范定义的保留宏符号。
- 函数替换宏早期定义是这样:#define dbgprint(format,...) printf (format, __VA_ARGS__),但是由于在实现中遇到如dbgprint("debug infomation!"),这种单纯的无可变参数调用方式,导致按照宏展开时,输入参数多了一个逗号“,”,会发生编译错误,因此后期使用了宏连接符“##”进行扩展,该扩展的作用是当可变参数宏没有可变参数时,在替换的时候就将format后边的逗号去掉,以此保证对于无可变参数宏的调用情况也可以正常编译。
本文所指的常量是指使用const修饰定义的数据。例如:
const float pi = 3.14;
const int max_num = 1000;
inline 函数,又被称为内联函数,是编译器在编译时根据资源消耗会将函数在调用处进行直接展开,可能不会进行普通函数调用过程(pc指针跳转,参数出栈入栈等)的函数,inline函数只有在定义的时候使用inline标识才有效,声明使用inline但是定义没有,那么inline标识是无效的,且一般建议声明时不适用inline标识。
__inline int max(int a,int b)
{
if(a > b)
{
return a;
}else
{
return b;
}
}
四.define,const,inline三者的区别和联系
实际上const和inline都是对define的一个增补,因为宏命令define只是发生在预编译期间,仅仅完成对源码的一种符号替换。不具备错误检查方式,参数检查等等,主要缺点如下表:
- #define test 3388;在源文件中使用test的时候,如果发生错误,错误提示会指明源文件某行的3388出错,实际上问题发生在est宏,源行找不到3383这个数,这就带来不好调试的问题
- 宏作为函数输入参数时,编译期间无法进行参数匹配检查,导致某些错误不能被提前发现
- 宏max(a,b)使用过程需要注意参数是表达式时容易引起歧义,导致展开出错,如max(2+3,2+9)展开为(2+3 > 2+9 ? 2+3 : 2+9)和初期的设计相去甚远
- 参数宏在被频繁调用时,必然会被频繁展开,增大代码体积。
为了避开宏的以上缺点同时保留其简单,直观,简洁,易维护等优点,新增了const常量和inline函数。
- const常量用于替换宏的一般常量定义
- inline函数用于替换带参数的宏的情况
- 对于那些必须要在预编译阶段执行的动作不能用以上两种方式对宏进行替换。例如数组大小的宏;为了便于调试对printf进行替换的宏;条件编译的宏等