C++内联函数的用法(非常详细)
在 C++ 中,系统在执行函数调用时会进行一系列额外的操作,如保存和恢复现场环境、参数赋值等。这些操作对于短小且频繁调用的函数来说,可能会导致函数调用的开销超过函数体实际执行的时间,从而影响程序的整体性能。
为了优化这种情况,C++ 引入了内联函数(inline function)的概念。
在 C++ 中,当一个函数被声明为内联函数时,编译器会尝试将该函数的代码直接嵌入到每个调用点,从而避免函数调用的额外开销。这种做法尤其适用于那些执行速度快且体积小的函数,它们的代码可以被直接展开,以提高程序的执行效率。
当编译器编译程序时,如果发现某段代码调用的是一个内联函数,那么它不会去调用该函数,而是将该函数的代码直接插入到当前函数调用的位置。
这样做法虽然会在一定程度上增加程序的体积,但会省去函数调用过程中的那些烦琐的幕后工作,从而提高代码的执行效率,也就是通过增加程序空间来换取了执行时间的减少。
内联函数是对函数的一种修饰,我们只需要在普通函数的定义前加上 inline 关键字,就可以把它修饰为内联函数。其语法格式如下:
例如,前面的 Add() 函数会被频繁调用且较为简短,我们可以在其定义前加上 inline 关键字,将其声明为一个内联函数:
当一个函数成为内联函数后,其调用形式与普通函数的调用形式没有任何区别,例如:
只有在遵循以下内联函数的使用规则时,才能在程序体积和性能之间实现平衡,充分利用内联函数的优势来提高程序的性能。
如果将一个比较复杂的函数内联,往往会导致程序的体积迅速膨胀,最后可能得不偿失。
如果函数执行的时间远大于函数调用过程中所需的开销(即那些幕后工作所花费的时间),那么通过内联函数节省下来的那一点时间也就无足轻重了。
反过来,编译器在优化时也可能将未标记为 inline 的函数进行内联处理,只要编译器“认为”该函数内联会提高代码性能,也就是说,编译器也会自作主张地将函数进行内联处理。
因此,inline 关键字只是表示建议,是否内联最终还是由编译器决定。
虽然内联函数可以在一定程度上提高程序的性能,但它并非万能的性能解决方案,也并不是越多越好。当程序存在性能问题时,更应从程序的结构和设计入手寻找解决办法。内联函数可以视为程序优化的辅助手段,偶尔使用效果不错,但并不能完全替代其他性能优化方法。
为了优化这种情况,C++ 引入了内联函数(inline function)的概念。
在 C++ 中,当一个函数被声明为内联函数时,编译器会尝试将该函数的代码直接嵌入到每个调用点,从而避免函数调用的额外开销。这种做法尤其适用于那些执行速度快且体积小的函数,它们的代码可以被直接展开,以提高程序的执行效率。
C++内联函数的用法
内联是 C++ 对函数的一种特殊修饰,实际上,内联函数可以更形象地被称为内嵌函数。当编译器编译程序时,如果发现某段代码调用的是一个内联函数,那么它不会去调用该函数,而是将该函数的代码直接插入到当前函数调用的位置。
这样做法虽然会在一定程度上增加程序的体积,但会省去函数调用过程中的那些烦琐的幕后工作,从而提高代码的执行效率,也就是通过增加程序空间来换取了执行时间的减少。
内联函数是对函数的一种修饰,我们只需要在普通函数的定义前加上 inline 关键字,就可以把它修饰为内联函数。其语法格式如下:
inline 返回值类型标识符 函数名(形式参数表) { 函数体语句; }
例如,前面的 Add() 函数会被频繁调用且较为简短,我们可以在其定义前加上 inline 关键字,将其声明为一个内联函数:
// 内联的 Add()函数 inline int Add(int a, int b) { return a + b; }需要注意的是,如果一个函数的声明和定义是分开的,我们必须确保在函数定义之前使用 inline 关键字(为了提高代码的可读性,声明前也最好加上),这样才能使其成为一个内联函数。
当一个函数成为内联函数后,其调用形式与普通函数的调用形式没有任何区别,例如:
int main() { // 调用内联函数Add() int res = Add(2,3); return 0; }编译器在编译这段代码时,因为被调用的 Add() 函数是一个内联函数,它将不再进行常规的函数调用。编译器会直接把 Add() 函数的代码插入到函数调用的位置,从而省略了中间的函数调用过程,这在一定程度上提高了性能。
内联函数的使用规则
凡事都有利有弊。内联函数虽然能够在一定程度上提升程序性能,但因为内联函数需要在每个调用点插入该函数的代码,这将导致整个程序体积增大。只有在遵循以下内联函数的使用规则时,才能在程序体积和性能之间实现平衡,充分利用内联函数的优势来提高程序的性能。
1) 内联函数要短小精悍
内联函数的本质是将函数代码复制到函数调用的位置,这会增加程序的体积。因此,内联函数应尽量做到短小精悍,一般不要超过 5 行代码。如果将一个比较复杂的函数内联,往往会导致程序的体积迅速膨胀,最后可能得不偿失。
2) 内联函数执行的时间要短
内联函数不仅要简短,其执行时间也应尽可能短,以体现内联函数的优势。如果函数执行的时间远大于函数调用过程中所需的开销(即那些幕后工作所花费的时间),那么通过内联函数节省下来的那一点时间也就无足轻重了。
3) 内联函数应该被多次重复调用
内联函数通过避免函数调用的开销,在频繁调用时可以显著节省时间,从而提高程序性能。然而,这种优化有前提条件。如果一个内联函数仅被调用一次或少数几次,节省的时间可能微乎其微,甚至可以忽略不计。在这种情况下,内联函数可能会增加程序体积,因为它会将函数代码复制到每个调用点,导致代码冗余。4) inline关键字只是一种建议
inline 关键字只是对编译器的建议,表明程序员希望将函数内联处理。但是,编译器可以能会忽略这一建议,在某些特定的情况下将函数保持为普通函数,并给出相应的警告。反过来,编译器在优化时也可能将未标记为 inline 的函数进行内联处理,只要编译器“认为”该函数内联会提高代码性能,也就是说,编译器也会自作主张地将函数进行内联处理。
因此,inline 关键字只是表示建议,是否内联最终还是由编译器决定。
虽然内联函数可以在一定程度上提高程序的性能,但它并非万能的性能解决方案,也并不是越多越好。当程序存在性能问题时,更应从程序的结构和设计入手寻找解决办法。内联函数可以视为程序优化的辅助手段,偶尔使用效果不错,但并不能完全替代其他性能优化方法。