LBu*_*kin 120
预处理器宏只是应用于代码的替换模式.它们几乎可以在代码中的任何位置使用,因为在任何编译开始之前它们都会被扩展替换.
内联函数是实体函数,其主体直接注入其调用站点.它们只能在适合函数调用的地方使用.
现在,就类似函数的上下文中使用宏与内联函数而言,请注意:
Thi*_*hib 70
首先,预处理器宏只是编译前代码中的"复制粘贴".所以没有类型检查,可能会出现一些副作用
例如,如果要比较2个值:
#define max(a,b) ((a<b)?b:a)
Run Code Online (Sandbox Code Playgroud)
如果您使用max(a++,b++)
例如(a
或b
将增加两次),则会出现副作用.相反,使用(例如)
inline int max( int a, int b) { return ((a<b)?b:a); }
Run Code Online (Sandbox Code Playgroud)
Dat*_*her 14
内联函数由编译器扩展,其中宏由预处理器扩展,这仅仅是文本替换.Hence
在宏调用期间没有类型检查,而在函数调用期间完成类型检查.
由于重新评估参数和操作顺序,在宏扩展期间可能会出现不期望的结果和低效率.例如
#define MAX(a,b) ((a)>(b) ? (a) : (b))
int i = 5, j = MAX(i++, 0);
Run Code Online (Sandbox Code Playgroud)
会导致
int i = 5, j = ((i++)>(0) ? (i++) : (0));
Run Code Online (Sandbox Code Playgroud)宏扩展之前不会评估宏参数
#define MUL(a, b) a*b
int main()
{
// The macro is expended as 2 + 3 * 3 + 5, not as 5*8
printf("%d", MUL(2+3, 3+5));
return 0;
}
// Output: 16`
Run Code Online (Sandbox Code Playgroud)无法在宏中使用return关键字来返回值,就像函数一样.
内联函数可以重载
传递给宏的标记可以使用运算符##连接,称为Token-Pasting运算符.
宏通常用于代码重用,其中内联函数用于消除函数调用期间的时间开销(超时)(避免跳转到子例程).