inline内联函数

什么是内联函数

在C++语言中为了解决程序调用函数的效率问题引入了inline修饰符,表示为内联函数。

#include<iostream>
using namespace std;
inline void swap(int &a, int &b) {
	int c = a;
	a = b;
	b = c;
}
int main() {
	int a = 1, b = 2;
	swap(a, b);
}

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

//错误的!!!
inline void fun(); 
void fun() {
	cout << "1" << endl;
}

内联函数的特征

  • inline只适合函数体内代码简单的函数使用,不能包含复杂的结构控制语句,如:while、switch,并且内联函数本身不能是直接递归函数。
  • inline函数一般用于比较小的、频繁调用的函数,这样可以减少函数调用带来的开销。只需要在函数返回类型前加上关键字inline,即可将函数指定为inline函数。

优缺点

优点:

  • 在内联函数被调用的地方进行代码展开,省去函数调用的时间,从而提高程序运行效率。
  • 相比于宏函数,内联函数在代码展开时,编译器会进行语法安全检查或数据类型转换,使用更加安全。

缺点:

  • 代码膨胀(代码的冗余和重复,进而增加了代码的体积和复杂度),产生更多的开销
  • 如果内联函数内代码块的执行时间比调用时间长的多,那么效率的提升并没有那么大;如果修改内联函数,那么所有调用该函数的代码文件都需要重新编译。
  • 内联声明只是建议,是否内联由编译器决定,所以实际并不可控。

编译器对内联函数的处理步骤

内联函数是一种特殊的函数,编译器在编译过程中会尝试将其“内联”到调用它的代码中,以避免函数调用的开销。编译器对内联函数的处理步骤通常如下:

  1. 解析内联函数的声明和定义:编译器会首先解析内联函数的声明和定义,并生成相应的函数符号表和语法树。

  2. 检查内联函数是否符合内联条件:编译器会检查内联函数是否符合内联条件,如函数的规模、复杂度、是否有递归调用等。如果不符合条件,则不进行内联处理,而是生成普通的函数调用。

  3. 将内联函数代码插入到调用点:如果内联函数符合条件,编译器会将内联函数的代码直接插入到调用点,以替换函数调用。这一步通常包括以下几个步骤:

    a. 替换函数调用:编译器会将函数调用的地方替换成内联函数的代码。

    b. 处理函数参数:编译器会将函数参数替换成对应的实参。

    c. 处理函数返回值:编译器会将函数返回值的地方替换成对应的表达式。

  4. 优化内联函数的代码:在将内联函数的代码插入到调用点之后,编译器还会进行一些代码优化,如常量折叠、无用代码删除、循环展开等,以进一步提高代码的执行效率。

  5. 生成最终的机器码:最后,编译器会将优化后的代码生成最终的机器码,并将其写入目标文件中,以供链接器进行链接。

虚函数可以是内联函数吗

通常情况下,虚函数是不能被内联的,虚函数的调用机制会限制内联函数的效果。因为虚函数的调用需要通过虚表来实现,当调用虚函数时,编译器需要通过虚表来确定需要调用哪个函数,因此虚函数的调用点不能被完全替换为函数体。而内联函数则是在编译期间将函数体嵌入到调用处,因此虚函数在被声明为内联函数时,其虚表指针的处理会有所不同,可能会导致内联函数的效果无法发挥。因此,不建议将虚函数声明为内联函数。

虚函数是否可以被内联,这通常是由编译器自行决定的,而不是由程序员手动指定的。

内联函数和函数的区别

  • 内联函数需要用inline关键字
  • 普通函数在被调用时,需要寻址(函数入口地址);内联函数不需要寻址
  • 内联函数有一定的限制,内联函数体要求代码简单,不能包含复杂的结构控制语句;普通函数没有这个要求。

内联函数和宏函数的区别

  • 宏定义不是函数,但使用起来像函数。预处理器用复制宏代码的方式代替函数的调用,省去了函数压栈退栈的过程,提高了效率;而内联函数本质上是一个函数,内联函数一般用于函数体代码比较简单的函数。
  • 内联函数是在编译时展开,宏函数是在预处理是展开;在编译时,内联函数直接被嵌入到目标代码中去,而宏只是一个简单的文本替换。
  • 宏定义是没有类型检查的,无论对错都是直接替换;内联函数在编译时会进行类型检查,内联函数满足函数的性质,比如有返回值、参数列表等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值