一、什么是内联函数

在C语言中,如果一些函数被频繁调用,不断地有函数入栈,即函数栈,会造成栈空间或栈内存的大量消耗。

为了解决这个问题,特别的引入了inline修饰符,表示为内联函数。

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

下面我们来看一个例子:

#include <stdio.h>

//函数定义为inline即:内联函数
inline char* dbtest(int a)
{
return (i % 2 > 0) ? "奇" : "偶";
}

int main()
{
int i = 0;
for (i=1; i < 100; i++)
{
printf("i:%d 奇偶性:%s /n", i, dbtest(i));
}
}
     上面的例子就是标准的内联函数的用法,使用inline修饰带来的好处我们表面看不出来,其实在内部的工作就是在每个for循环的内部任何调用dbtest(i)的地方都换成了(i%2>0)?"奇":"偶"这样就避免了频繁调用函数对栈内存重复开辟所带来的消耗。

其实这种有点类似咱们前面学习的动态库和静态库的问题,使 dbtest 函数中的代码直接被放到main 函数中,执行for 循环时,会不断调用这段代码,而不是不断地开辟一个函数栈。

二、内联函数的编程风格

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

如下风格的函数Foo 不能成为内联函数:

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

}
而如下风格的函数Foo 则成为内联函数:

void Foo(int x, int y);
inline void Foo(int x, int y) // inline 与函数定义体放在一起
{

}
       所以说,inline 是一种“用于实现的关键字”,而不是一种“用于声明的关键字”。一般地,用户可以阅读函数的声明,但是看不到函数的定义。尽管在大多数教科书中内联函数的声明、

定义体前面都加了inline 关键字,但我认为inline 不应该出现在函数的声明中。这个细节虽然不会影响函数的功能,但是体现了高质量C++/C 程序设计风格的一个基本原则:

声明与定义不可混为一谈,用户没有必要、也不应该知道函数是否需要内联。

2、inline的使用是有所限制的

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

三、慎用内联

内联能提高函数的执行效率,为什么不把所有的函数都定义成内联函数?如果所有的函数都是内联函数,还用得着“内联”这个关键字吗?

内联是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收
获会很少。另一方面,每一处内联函数的调用都要复制代码,将使程序的总代码量增大,消耗更多的内存空间。

以下情况不宜使用内联:

(1)如果函数体内的代码比较长,使用内联将导致内存消耗代价较高。

(2)如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大。

一个好的编译器将会根据函数的定义体,自动地取消不值得的内联(这进一步说明了inline 不应该出现在函数的声明中)。

总结:

因此,将内联函数放在头文件里实现是合适的,省却你为每个文件实现一次的麻烦.而之所以声明跟定义要一致,其实是指,如果在每个文件里都实现一次该内联函数的话,那么,

最好保证每个定义都是一样的,否则,将会引起未定义的行为,即是说,如果不是每个文件里的定义都一样,那么,编译器展开的是哪一个,那要看具体的编译器而定.

所以,最好将内联函数定义放在头文件中. 

最新文章

  1. Centos7安装完毕后无法联网的解决方法
  2. B-Tree 学习
  3. SE03 打包请求
  4. FCKeditor漏洞利用
  5. 使用Antlr实现简单的DSL
  6. jstl简介
  7. TFS源代码管理
  8. Winfrom 表格单元格格式化事件(DataGridView - CellFormatting)
  9. OpenGL的状态机理解
  10. 针对ie9写特殊的样式
  11. org.apache.commons.lang3.StringUtils类中isBlank和isEmpty方法的区别
  12. cURL: Learning..
  13. 001---Hibernate简介( 开源O/R映射框架)
  14. Algorithm --&gt; 树中求顶点A和B共同祖先
  15. Windows已遇到关键问题,将在一分钟后自动重新启动,请立即保存工作
  16. DAY3(PYTHON)字符串切片
  17. C++: 可变参数;
  18. Linux常用系统信息查看命令
  19. 用call/cc合成所有的控制流结构
  20. Seqlite学习

热门文章

  1. Daily Scrum 12.8
  2. css3-弹性盒模型
  3. eclipse html 打开方式
  4. \r\n
  5. codeforces 873C - Strange Game On Matrix
  6. 好消息,Manjaro Linux 18 已正式发布!
  7. 有源汇有上下界最小流 DInic + 各种优化 模板
  8. c# 对象存cookie
  9. MT【234】正方形染色(二)
  10. 【Luogu1937】仓配置(贪心,线段树)