内联函数
- 一.宏函数
- 二.内联函数
- 三,是否成为内联函数
- 四.内联函数的跨文件使用
一.宏函数
在c语言中,如果一个函数较短并且会被重复使用,那么我们就可以把该函数换成一个宏函数。
贴个小知识,宏函数有许多的坑也是面试官喜欢考的点,如果对行函数不太了解可以看看这篇关于宏的部分传送门
宏函数的优点:不会建立栈帧,提高使用效率。
宏函数的缺点:复杂,可读性差,不能调试。
为了解决宏函数的种种缺陷,c++推出了一个新的语法内联函数(inline)。
二.内联函数
内联函数的创建非常简单,只需要在普通的函数前面加上一个inline就可以了。
内联函数成功的解决了宏函数的种种问题,它的可读性强,不需要建立栈帧,简单并且可以调试。
既然内联函数优点这么多,那么可不可以把所有函数都改成内联函数呢?
答案是不可以。
内联函数跟宏函数一样都只适用于短小并且重复使用的函数。如果函数过长,会出现一个问题-代码膨胀。因为内联函数的本质就是展开:如果一个函数有50行代码并且会被调用10000次。那么如果该函数不是内联函数,编译器总共会执行指令10000+50=10050次;如果该函数是内联函数,那么编译器会执行指令10000*50=500000次。
如果在工程里出现了以上的问题,会造成什么后果呢?答案是会造成你的程序或者安装包的内存占用变大,如果同一个程序别人几百个MB就能完成,你的却需要好几个G,那很明显是不符合客户需求的。
三,是否成为内联函数
为了防止内敛函数被乱用,编译器自己有一套判断方法。
接下来,我们来测试一下,这个函数会不会变成内联。
这个函数短小并且被重复调用,按理说编译器应该支持内联,但这里很明显并没有(注意call指令出现就是一个明显的调用函数指令,说明该函数并未展开)。这是因为我编译器现在处于默认的Debug版本,在该版本下内联函数不会展开,否则不易调试。需要转到release版本,内联函数才会展开。
插个小知识,调试也是写程序非常重要的一环,如果不太了解可以看看这篇vs调试技巧
总结
四.内联函数的跨文件使用
在工程项目中,一直都是进行模块化编程,如果我像其他函数一样声明会出现什么问题呢?
我们在Add.cpp里定义,在Add.h里声明,在Test.cpp里使用,如果普通函数是不会有问题的,但是内联函数就会出现问题,并且报错是无法解析的外部符号,这也是标准的链接错误。
为什么会出现这种报错呢?这是因为内联函数不会进入符号表,也就是不会产生地址。而编译器在链接到Add.h里时,发现了Add函数的声明,自动生成了一个地址,但在Add.cpp里时,Add函数已经展开,不再有地址,所以编译器拿着这个地址但早不到定义,自然也就是无法解析。
内联函数跨文件应该如下写:
直接在Add.h里面定义,那么它就会像其它头文件时,在使用时自动展开啦。