函数可以用宏定义,例如
int main()
{
if (ADD(1, 2))//不能使用分号
{
}
ADD(1, 2) * 3;//外括号不能少
ADD(1 & 2, 3 | 4);//内括号不能少,因为+优先级高于&和|,会先计算2+3
return 0;
}
在编译期间编译器会将宏ADD函数体替换函数的调用。
宏函数的优点:
1.增强代码的复用性。
2.提高性能
缺点是:
1.不方便调试宏。(因为预编译阶段进行了替换)
2.导致代码可读性差(容易写错,漏括号和多写分号),可维护性差,容易误用。
3.没有类型安全的检查 。
C++中可以用内联函数代替宏函数。
1、内联函数的概念
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调
用建立栈帧的开销,内联函数提升程序运行的效率。
未使用inline函数时,调用了add函数:
当使用inline函数时,未调用add,在编译期间编译器会用函数体替换函数的调用
查看方式:
1. 在release模式下,查看编译器生成的汇编代码中是否存在call Add;
2. 在debug模式下,需要对编译器进行设置,否则不会展开(因为debug模式下,编译器默认不会对代码进行优化,以下给出vs2013的设置方式)
2、内联函数的特性
- inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大(代码膨胀,假如有1000个调用的地方,inline函数有30指令,展开后可能有30W),优势:少了调用开销,提高程序运行效率。
2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。(一般来说,内联机制使用于规模较小、流程直接、调用频繁的函数。很多编译器都不支持内联递归函数,而且一个75行的函数也不大可能在调用点内联的展开)
3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。
如果是正常的函数调用:
如果是内联函数,会进行报错(无法识别的外部符号):
报错原因看图:
那如何解决这个问题呢?解决方法:避免内联函数声明和定义分离,在声明的时候就一起定义: