C++内联函数(inline)

C++内联函数教程

C 语言 中,如果一些 函数 被频繁调用,不断地有函数入栈,即函数栈,会造成栈空间或栈内存的大量消耗。在 C++ 中,为了解决这个问题,特别的引入了 inline 修饰符,表示为内联函数。

栈空间就是指放置程式的局部数据也就是函数内数据的内存空间,在系统下,栈空间是有限的,假如频繁大量的使用就会造成因栈空间不足所造成的程式出错的问题,函数的死循环 递归调用 的最终结果就是导致栈内存空间枯竭。

内联函数使用场景

函数是一个可以重复使用的代码块,CPU 会一条一条地挨着执行其中的代码。CPU 在执行主调函数代码时如果遇到了被调函数,主调函数就会暂停,CPU 转而执行被调函数的代码;被调函数执行完毕后再返回到主调函数,主调函数根据刚才的状态继续往下执行。

一个 C/C++ 程序的执行过程可以认为是多个函数之间的相互调用过程,它们形成了一个或简单或复杂的调用链条,这个链条的起点是 main(),终点也是 main()。当 main() 调用完了所有的函数,它会返回一个值(例如 return 0;)来结束自己的生命,从而结束整个程序。

函数调用是有时间和空间开销的。程序在执行一个函数之前需要做一些准备工作,要将实参、局部变量、返回地址以及若干寄存器都压入栈中,然后才能执行函数体中的代码;函数体中的代码执行完毕后还要清理现场,将之前压入栈中的数据都出栈,才能接着执行函数调用位置以后的代码。

如果函数体代码比较多,需要较长的执行时间,那么函数调用机制占用的时间可以忽略;如果函数只有一两条语句,那么大部分的时间都会花费在函数调用机制上,这种时间开销就就不容忽视。

为了消除函数调用的时空开销,C++ 提供一种提高效率的方法,即在编译时将函数调用处用函数体替换,类似于 C 语言中的宏展开。这种在函数调用处直接嵌入函数体的函数称为内联函数(Inline Function),又称内嵌函数或者内置函数。

C++内联函数详解

定义

关键字 inline 必须与函数定义体放在一起才能使函数成为内联,仅将 inline 放在函数声明前面不起任何作用。

语法

inline returntype funcname(paramterType params) // inline 与函数定义体放在一起 { return [val]; }

参数

参数 描述
inline 定义内联函数使用的关键字。
returntype 函数的返回值类型。
funcname 函数名。
paramterType 函数的参数类型。
params 函数的形参。

说明

我们使用 inline 定义了一个内联函数 funcname,该函数的返回值类型为 returntype,函数的参数类型为 paramterType。

技术细节

如下的函数风格,不是内联函数,因为内联函数的 inline 关键字,只能放在函数定义的地方:

inline void Foo(int x, int y); // inline 仅与函数声明放在一起 void Foo(int x, int y) { }

inline关键字

inline 是一种 “用于实现的关键字”,而不是一种 “用于声明的关键字”。一般地,用户可以阅读函数的声明,但是看不到函数的定义。尽管在大多数教科书中内联函数的声明、定义体前面都加了 inline 关键字,但我认为 inline 不应该出现在函数的声明中。

这个细节虽然不会影响函数的功能,但是体现了高质量 C++/C 程序设计风格的一个基本原则:声明与定义不可混为一谈,用户没有必要、也不应该知道函数是否需要内联。

使用限制

inline 的使用是有所限制的,inline 只适合涵数体内代码简单的函数数使用,不能包含复杂的结构控制语句例如 whileswitch 并且内联函数本身不能是直接递归函数(自己内部还调用自己的函数)。

案例

C++内联函数使用

C++ 中使用 inline 定义内联函数

#include <iostream> using namespace std; inline bool isEven(int num) { return num % 2 == 0; } int main() { cout << "嗨客网(www.haicoder.net)\n" << endl; int num1 = 1024; int num2 = 109; bool num1IsEven = isEven(num1); bool num2IsEven = isEven(num2); cout << "num1IsEven = " << num1IsEven << "num2IsEven = " << num2IsEven << endl; return 0; }

程序运行后,控制台输出如下:

16_C内联函数inline.png

我们使用 inline 定义了一个内联函数 isEven,该函数返回一个 bool 类型的 变量,用于表示传入的参数是否为偶数,我们可以看到,我们定义的函数的函数体非常小,就一句话,因此非常适合使用内联函数。

C++内联函数总结

inline 是一种 “用于实现的关键字”,而不是一种 “用于声明的关键字”。一般地,用户可以阅读函数的声明,但是看不到函数的定义。尽管在大多数教科书中内联函数的声明、定义体前面都加了 inline 关键字,但我认为 inline 不应该出现在函数的声明中。

这个细节虽然不会影响函数的功能,但是体现了高质量 C++/C 程序设计风格的一个基本原则:声明与定义不可混为一谈,用户没有必要、也不应该知道函数是否需要内联。

inline 的使用是有所限制的,inline 只适合涵数体内代码简单的函数数使用,不能包含复杂的结构控制语句例如 while、switch 并且内联函数本身不能是直接递归函数(自己内部还调用自己的函数)。