[牛人杂谈] C/C++内联函数和extern "C"问题讨论

[复制链接]
1086|8
 楼主| zhuomuniao110 发表于 2016-10-26 20:42 | 显示全部楼层 |阅读模式
内联(inline)函数
       提到内联函数,先看下面两个程序,程序的执行结界都是为了得到两个值相加之和:
  1. int add(int x,int y)
  2. {
  3.     return x+y;
  4. }

  5. int main(int argc,char* argv[])
  6. {
  7.     int a=1,b=2,c;
  8.     c=add(a,b);          //通过调用函数的形式得到相加结果
  9.     return 0;
  10. }

  11. //程序2
  12. int main(int argc,int argv[])
  13. {
  14.     int a=1,b=2,c;
  15.     c=a+b;               //直接计算得到相加结果  
  16.     return 0;
  17. }


 楼主| zhuomuniao110 发表于 2016-10-26 20:43 | 显示全部楼层
上面哪个程序的执行效率更高?
      答案是“程序2”是c=a+b直接计算得到相加结果,而“程序1”是通过函数调用c=add(a,b)得到相加的结果。“程序2”的直接计算,节省了函数调用、参数传值、控制权转移等开销,执行效率比“程序1”的函数调用要快得多。
      然而,实际工作中,可能会更多地采用“程序1”的函数调用方式,因为从功能封装和重复使用上来说,通常会将一段通用的程序片段进行封装,以便在其他需要相同功能的地方调用。这就产生了一个矛盾,如果将一段特定功能的代码封装成一个函数,就会大大降低程序效率。
      为了解决这个问题,C++引入了内联函数的概念。内联函数给出了一种解决方案:如果一个函数被指定为内联(inline)函数,则它将在调用点上被“内联”地展开,内联函数不是在调用时发生控制转移,而是在编译时将函数体嵌入在调用处。
       这意味着,编写代码时,可以采用“程序1”的函数调用形式,等到编译时,编译器会把“程序1”方式编译成“程序2”的方式,这就是内联函数的优点所在。唯一要做的就是,在“程序1”中加入关键字inline。

  1. //程序3
  2. inline int add(int x,int y)  //声明为内联(inline)函数
  3. {
  4.     return x+y;
  5. }

  6. int main(int argc,char* argv[])
  7. {
  8.     int a=1,b=2,c;
  9.     c=add(a,b);         
  10.     return 0;
  11. }
注意:所谓inline函数,只是对C++编译器的一个建议。C++编译器可以选择忽略这个建议,比如对于大于1200行的函数,或者递归调用的函数,或者用到递归调用的函数,通常C++编译器都不会编译成内联函数。

extern "C"
      时常在C++的代码之中看到这样的代码:
  1. #ifdef _cplusplus
  2. extern "C" {
  3. #endif

  4. //一段代码

  5. #ifdef _cplusplus
  6. }
  7. #endif




 楼主| zhuomuniao110 发表于 2016-10-26 20:44 | 显示全部楼层
这样的代码到底是什么意思呢?首先,_cplusplus是C++中的自定义宏,那么定义了这个宏则表示这是一段C++的代码,也就是说,上面的代码的含义是:如果这是一段C++的代码,那么加入extern "C"{和}处理其中的代码。
      要明白为何使用extern "C",还得从C++中的重载函数入手。在C++中,为了支持重载机制,在编译生成的汇编码中,要对函数的名字进行一些处理,加入比如函数的返回类型等等。而在C中,只是简单的函数名字而已,不会加入其他的信息。也就是说:C++和C对产生的函数名字的处理是不一样的。所以,一句话,加入extern "C"是防止名字改编。
      C和C++对函数的处理方式是不同的。extern "C"是使C++能够调用C写的库文件的一个手段,如果要对编译器提示使用C的方式来处理函数的话,那么就要使用extern "C"来说明。

Roderman_z 发表于 2016-10-26 21:22 | 显示全部楼层
默认都是内联的函数吧
mintspring 发表于 2016-10-27 11:44 | 显示全部楼层
第一次了解这个概念,很深奥。
mintspring 发表于 2016-10-27 11:45 | 显示全部楼层
内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。内联函数不是在调用时发生控制转移,而是在编译时将函数体嵌入在每一个调用处。编译时,类似宏替换,使用函数体替换调用处的函数名。一般在代码中用inline修饰,但是能否形成内联函数,需要看编译器对该函数定义的具体处理。
diweo 发表于 2016-10-27 20:56 | 显示全部楼层
Roderman_z 发表于 2016-10-26 21:22
默认都是内联的函数吧

在类定义内部定义的函数是默认内联的,其他函数默认不内联。
 楼主| zhuomuniao110 发表于 2016-10-30 15:37 | 显示全部楼层
以前不懂具体什么意思,总是看到in line,这个概念,专门找了资料学习,并分享给大家。
 楼主| zhuomuniao110 发表于 2016-11-13 22:00 | 显示全部楼层
C 语言这么牛叉,你不深入研究是无法理解的。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

233

主题

3529

帖子

11

粉丝
快速回复 在线客服 返回列表 返回顶部