引入内联函数的目的是为了解决程序中函数调用的效率问题,也是用内联函数取代带参宏定义(函数传参比宏更加方便易用)

inline关键字用来定义一个类的内联函数。

在类体中和类体外定义成员函数是有区别的:在类体中定义的成员函数为内联(inline)函数,在类体外定义的不是。如果你既希望将函数定义在类体外部,又希望它是内联函数,那么可以在声明函数时加 inline 关键字.在类体内部定义的函数也可以加 inline 关键字,但这是多余的,因为类体内部定义的函数默认就是内联函数.如果在类体外定义 inline 函数,则必须将类定义和成员函数的定义都放在同一个头文件中(或者写在同一个源文件中),否则编译时无法进行嵌入。

inline定义的类的内联函数,函数的代码被放入符号表中,在使用时直接进行替换,(像宏一样展开),没有了调用的开销,效率也很高。类的内联函数也是一个真正的函数,编译器在调用一个内联函数时,会首先检查它的参数的类型,保证调用正确。然后进行一系列的相关检查,就像对待任何一个真正的函数一样。这样就消除了它的隐患和局限性。inline可以作为某个类的成员函数,当然就可以在其中使用所在类的保护成员及私有成员。

inline使用场景:(1)、可以使用inline函数完全取代表达式形式的宏定义;(2)、内联函数一般只会用在函数内容非常简单的时候,这是因为,内联函数的代码会在任何调用它的地方展开,如果函数太复杂,代码膨胀带来的恶果很可能会大于效率的提高带来的益处。

在程序编译时,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体来进行替换。显然,这种做法不会产生转去转回的问题,但是由于在编译时将函数体中的代码被替代到程序中,因此会增加目标程序代码量,进而增加空间开销,而在时间开销上不像函数调用时那么大,可见它是以目标代码的增加为代价来换取时间的节省。内联函数可减少cpu的系统开销,并且程序的整体速度将加快,但当内联函数很大时,会有相反的作用,因此一般比较小的函数才使用内联函数.

有两种内联函数的声明方法,一种是在函数前使用inline关键字,另一种是在类的内部定义函数的代码,这样的函数将自动转换为内联函数,而且没必要将inline放在函数前面。

内联是一种对编译器的请求,下面这些情况会阻止编译器服从这项请求:如果函数中包含有循环,switch或goto语句,递归函数,含有static的函数.

由此可以看出,内联函数和成员函数没什么区别,区别就在于怎样加快函数的执行速度而已。内联函数是浪费空间来节省时间的设置,因为函数的调用是很浪费时间的,写成内联函数可以在每次调用时用函数体内容代替函数调用,有点类似一个宏定义。当函数体语句较少,且没有复杂的循环语句,且调用次数较多时,就可以用内联函数。

内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。编译时,类似宏替换,使用函数体替换调用处的函数名。一般在代码中用inline修饰,但是否能形成内联函数,需要看编译器对该函数定义的具体处理。

"static inline" means "we have to have this function, if you use it, but don't inline it, then make a static version of it in this compilation unit". "extern inline" means "I actually _have_ an extern for this function, but if you want to inline it, here's the inline-version".

static是以前C的用法.目的是让该关键字标识的函数只在本地文件可见,同一个程序的其它文件是不可见该函数的.换句话说,就算你其它文件里包含了同名同参数表的函数定义的话,也是不会引起函数重复定义的错误的.因为static是仅在当前文件可见。

static inline,静态内联函数,它不使用函数调用,直接将汇编代码插入在调用该函数处。

static inline,可以把它认为是一个static的函数,加上了inline的属性。static inline函数和static函数一样,其定义的范围是local的,即可以在程序内有多个不同的定义(只要不位于同一个文件内即可)。

static inline的内联函数,一般情况下不会产生函数本身的代码,而是全部被嵌入在被调用的地方。如果不加static,则表示该函数有可能会被其他编译单元所调用,所以一定会产生函数本身的代码。所以加了static,一般可令可执行文件变小。Linux内核使用的inline函数大多被定义为static 类型。一个"static inline"函数促使编译程序尝试着将其代码插入到所有调用它的程序中。

extern inline表示该函数是已声明过的了.由于函数本身可以声明多次,所以extern对函数的影响仅仅把函数的隐藏属性显式化了. extern 对于非函数的对象是有用的,因为对象声明时会带来内存的分配,而用 extern就表示该对象已经声明过了,不用再分配内存。

extern inline函数的应用范围比较狭窄,一般不建议使用。

以上内容主要整理自:

1. http://www.cnblogs.com/pengyingh/articles/2405718.html

2. http://stackoverflow.com/questions/216510/extern-inline

3. http://wenku.baidu.com/link?url=QVc0SQBmFKDjcz65nQRe5wqsaY-rBp89VAu9iX6aCm2avMORW-IeGf_zYxFYRf4vNi7P-G3eFc7sx_FzzUh2r2EoXEGajf9MWxVm1_sJsVO

以下为测试代码:

static_inline.h:

#ifndef FBC_MESSY_TEST_STATIC_INLINE_HPP_
#define FBC_MESSY_TEST_STATIC_INLINE_HPP_class FastMath {
public:int round(float value) { //类体内部定义的函数默认就是内联函数,也可以加 inline 关键字,但这是多余的return (int)(value + (value >= 0 ? 0.5f : -0.5f));}inline int floor(float value); // 声明为内联函数
};int FastMath::floor(float value)
{int i = round(value);float diff = (float)(value - i);return i - (diff < 0);
}static inline int Ceil(float value)
{int i = (int)(value + (value >= 0 ? 0.5f : -0.5f));float diff = (float)(i - value);return i + (diff < 0);
}void test_static_inline1();
void test_static_inline2();#endif // FBC_MESSY_TEST_STATIC_INLINE_HPP_

static_inline.cpp:

#include "static_inline.hpp"
#include <iostream>void test_static_inline1()
{float a = 4.1, b = 4.9;FastMath math;int ret1 = math.round(a);int ret2 = math.floor(a);int ret3 = math.round(b);int ret4 = math.floor(b);std::cout << ret1 << "   " << ret2 << "    " << ret3 << "    " << ret4 << std::endl;
}void test_static_inline2()
{float a = 4.1, b = 4.9;int ret1 = Ceil(a);int ret2 = Ceil(b);std::cout << ret1 << "    " << ret2 << "    " << std::endl;
}

GitHub: https://github.com/fengbingchun/Messy_Test

C/C++中inline/static inline/extern inline的区别及使用相关推荐

  1. php static 和 global,php中global static和$GLOBALS使用与区别

    本文章来总结介绍关于php中global static和$GLOBALS使用与区别有需要了解他们三区别的朋友可参考参考. 1.global在整个页面起作用. 例1  代码如下 复制代码 global ...

  2. php new static,PHP中new static()与new self()的区别异同分析

    本文实例讲述了PHP中new static()与new self()的区别异同,相信对于大家学习PHP程序设计能够带来一定的帮助. 问题的起因是本地搭建一个站.发现用PHP 5.2 搭建不起来,站PH ...

  3. 浅谈C/C++中的static和extern关键字

    一.C语言中的static关键字 在C语言中,static可以用来修饰局部变量,全局变量以及函数.在不同的情况下static的作用不尽相同. (1)修饰局部变量 一般情况下,对于局部变量是存放在栈区的 ...

  4. PHP 中 new static 和 new self 的区别

            今天老大在公司 问了一下  new static  和 new self 的区别 公司十个程序 竟然没有一个回答上来 后面画面自补 ... 本屌丝回家后 就百度了解了下 这二者区别 : ...

  5. OC中使用 static 、 extern、 const使用

    static static用于定义静态变量,静态变量只会被初始化一次,并且直到程序销毁时才会释放 static NSString *str = @"asdfa"; const co ...

  6. dim private public static_PHP中const,static,public,private,protected的区别

    const: 定义常量,一般定义后不可改变 static: 静态,类名可以访问 public: 表示全局,类内部外部子类都可以访问: private: 表示私有的,只有本类内部可以使用: protec ...

  7. c语言函数声明中,static inline和extern inline的区别

    c语言函数声明中,static inline和extern inline的区别 "extern"关键字对于普通函数没有作用 "extern"和"sta ...

  8. c语言头文件中定义inline static相关函数的优劣

    头文件中常见static inline函数,于是思考有可能遇到的问题,如头文件经常会被包含会不会产生很多副本?网上说法不一.于是自己验证.经过arm-none-eabi-gcc下测试后得出结论. in ...

  9. 关于头文件中的 static inline函数

    关于头文件中的 static inline函数 头文件中常见static inline函数,于是思考有可能遇到的问题,如头文件经常会被包含会不会产生很多副本?网上说法不一.于是自己验证.经过arm-n ...

最新文章

  1. 使用WinPcap和libpcap类库读写pcap文件(001)开发环境配置
  2. 禁掉人脸识别!一群音乐人正在号召,禁止在音乐节上动用人脸识别
  3. AFNetworking 对数据进行https ssl加密
  4. 深度思考 Spring Cloud + Alibaba Sentinel 源码原理
  5. 6.IDA-重命名、注释
  6. 百度地图3.2教程(2)公交查询
  7. TurboMail邮件服务器推动邮件领域的进一步发展
  8. 实现fashion_minst服装图像分类
  9. 【ANSYS命令流】为什么是命令流?
  10. excel合并两列内容_【238期】EXCEL扩展思维,一题多解,玩转数据两列合并,你都会?...
  11. 100部经典中国电影,你看过几部?
  12. Spring Boot(一)之入门篇
  13. 科隆国际游戏展:2000系列显卡来袭,iGame板卡信仰搭配
  14. 篇2:基于windows10专业版搭建ftp服务器
  15. 详细介绍MVC与Django的MVT模式
  16. 软件变异体测试(mutation test)
  17. 局域网访问提示无法访问检查拼写_win10无法访问局域网电脑 请检查名称的拼写...
  18. JavaScript——leetcode2006 差的绝对值为k的数对数目
  19. Jflash 命令行 烧录程序 注意事项
  20. 关于速卖通你应该知道的一些操作

热门文章

  1. 生成式对抗网络的原理和实现方法
  2. tensorflow deep_speech2 神经网络结构代码分析
  3. Mat,Iplimage,vector,vector_vector_Point2f等类型之间的相互转换
  4. 电脑雕刻教程_理性看待手工雕刻和电脑雕刻,手工并不代表精品,电脑雕刻也不代表战五渣...
  5. Gmapping从开始到放弃—写一个TF 监听
  6. CUDA硬件架构知识
  7. 【人尽其才】颠覆思维☞合理分配工作
  8. Rocksdb 的一些参数调优策略
  9. C++ 多线程:future 异步访问类(线程之间安全便捷的数据共享)
  10. 动态内存管理和智能指针 2.0 -- shared_ptr