个人主页 :阿然成长日记 点击可跳转
个人专栏: 数据结构与算法C语言进阶
不能则学,不知则问,耻于问人,决无长进
我们在C语言学习中学习了宏的相关知识,宏的定义:#define 机制包括了一个规定,允许把参数替换到文本中,这种实现通常称为宏(macro)或定义。通过宏定义的函数,在编译时,自动替换的函数调用位置,不会进行压栈等操作,可以提升效率,但是他的缺点也很明显,就是宏不支持调试的,也没有类型安全的检查,而且语法复杂。所以我们引进了内联函数。
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。
release
模式下,查看编译器生成的汇编代码中是否存在call
Adddebug
模式下,需要对编译器进行设置,否则不会展开,无法进行调试!(因为debug模式下,编译器默认不会对代码进行优化,以下给出vs2019的设置方式
第三步:点击优化–内联函数扩展–只适用于inline(/Ob1)
看一下代码:
定义了两个函数非内联函数Add1和内联函数Add2。
int Add1(int left, int right)
{
int ret1 = left + right;
return ret1;
}
inline int Add2(int x, int y)
{
int ret2 = x + y;
return ret2;
}
int main()
{
//非内联
int recive1 = Add1(4, 5);
//内联
int recive2 = Add2(5, 7);
return 0;
}
通过返汇编可以清楚的看到,内联函数的调用没有,push压栈等操作。
绿色方框内是非内联函数调用:可以发现使用了push
call
操作。
蓝色方框是内联函数:直接mov移动过来,全程没有压栈,出栈操作。
空间换时间
的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率不同编译器关于inline实现机制可能不同
,一般建议:将函数规模较小
(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归
、且频繁调用
的函数采用inline修饰,否则编译器会忽略inline特性。inline被展开,就没有函数地址了
,链接就会找不到。内联不是万能的,它以代码膨胀(拷贝)为代价,仅仅省区了函数调用的开销,从而提高程序的执行效率。(开销指的是参数的压栈、跳转、退栈和返回操作)。
(1)如果执行函数体内代码的时间比函数调用的开销大得多,那么inline效率收益会很小。
(2)每一处内联函数的调用都要拷贝代码,使程序的总代码量增大,消耗更多的内存空间。
(3)以下情况不宜使用内联:
总之:一般只将那些短小的、频繁调用的函数声明才使用内联函数。