宏定义和內联函数的区别

带参数的宏和普通函数

带参数的宏可以代替函数。宏的替换发生在预编译阶段,占据编译时间;函数调用发生在运行阶段,占据运行时间。对于一些比较大的函数:1.程序的主要运行时间集中在函数体上,函数调用开销可以忽略不计;2.如果函数体过长,宏替换会增加源码的长度,过长的源程序执行起来系统会频繁换页,导致执行效率变低,而函数则不会增加源程序长度。
基于这两个原因,对于函数体较短的函数,可以用带参数宏来替换,对于函数体较长的函数则不使用宏替换。
1.函数调用时,先求出实参表达式的值,然后带入形参。而使用带参的宏只是进行简单的字符替换。
2.函数调用是在程序运行时处理的,分配临时的内存单元;而宏展开则是在编译时进行的,在展开时并不分配内存单元,不进行值的传递处理,也没有“返回值”的概念。
3. 对函数中的实参和形参都要定义类型,二者的类型要求一致,如不一致,应进行类型转换;而宏不存在类型问题,宏名无类型,它的参数也无类型,只是一个符号代表,展开时带入指定的字符即可。宏定义时,字符串可以是任何类型的数据。
4. 函数体内有Bug,可以在函数体内打断点调试。如果宏体内有Bug,那么在执行的时候是不能对宏调试的,即不能深入到宏内部。
5. C++中宏不能访问对象的私有成员,但是成员函数就可以。
6. 宏的定义很容易产生二义性,如:定义#define S(a) (a)(a),代码S(a++),宏展开变成(a++)(a++)这个大家都知道,在不同编译环境下会有不同结果。

带参数的宏和内联函数

内联函数和宏的区别在于,宏是由预处理器对宏进行替代,而内联函数是通过编译器控制来实现的。而且内联函数是真正的函数,只是在需要用到的时候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开销。你可以象调用函数一样来调用内联函数,而不必担心会产生于处理宏的一些问题。
注:1.函数调用是有时间和空间开销的。程序在执行一个函数之前需要做一些准备工作,要将实参、局部变量、返回地址以及若干寄存器都压入栈中,然后才能执行函数体中的代码;函数体中的代码执行完毕后还要清理现场,将之前压入栈中的数据都出栈,才能接着执行函数调用位置以后的代码(分配单元、保留现场、值传递、返回)。
2.参考https://blog.nowcoder.net/n/e3110c5a12f042a38150edb0817e6c16