C++编程中队内联函数的理解和使用_C 语言

函数调用过程
c++经过编译生成可执行程序文件exe,存放在外存储器中。程序启动,系统从外存储器中将可执行文件装载到内存中,从入口地址(main函数起始处)开始执行。程序执行中遇到了对其他函数的调用,就暂停当前函数的执行,并保存下一条指令的地址作为从被调函数返回后继续执行的入口点,保存现场。然后转到被调函数的入口地址执行被调函数。遇到return语句或者被调函数结束后,恢复先前保存的现场,从先前保存的返回地址处继续执行主调函数的其余部分。

内联函数
函数调用需要进行现场保护,以便在函数调用之后继续进行。函数调用后还需要恢复现场才能继续执行。这都需要系统开销,影响了程序的效率。

内联函数在编译的时候将所调用的函数代码直接嵌入到主调函数中,定义方式就是在普通的函数定义前面加上inline,不存在程序流程跳转和返回,但是增加了程序代码。内联函数函数体不能含有复杂的结构控制语句,适用于1-5行的小函数。当函数规模比较大的时候,函数运行的时间相对与函数的调用和返回时间大很多,综合时间和空间考虑,用内联没有太大意义。

原理:
对于任何内联函数,编译器在符号表里放入函数的声明(包括名字、参数类型、返回值类型)。如果编译器没有发现内联函数存在错误,那么该函数的代码也被放入符号表里。在调用一个内联函数时,编译器首先检查调用是否正确(进行类型安全检查,或者进行自动类型转换,当然对所有的函数都一样)。如果正确,内联函数的代码就会直接替换函数调用,于是省去了函数调用的开销。

内联函数与宏的区别
1.内联函数在运行时可调试,而宏定义不可以;

2.编译器会对内联函数的参数类型做安全检查或自动类型转换(同普通函数),而宏定义则不会;

3.内联函数可以访问类的成员变量,宏定义则不能;

4.在类中声明同时定义的成员函数,自动转化为内联函数。

C++ 语言的函数内联机制既具备宏代码的效率,又增加了安全性,而且可以自由操作类的数据成员。所以在C++ 程序中,应该用内联函数取代所有宏代码

一个可执行文件的cpp文件中一个函数只能被定义一次。如果你把函数定义在一个.h文件中并让两个cpp包含就会造成这个函数分别在两个cpp中被定义产生错误。但是inline函数是允许在多个cpp中多次定义的,就解决了这个问题。

for (int i=v.begin() ; i<v.size() ; i++)
{
  ....
}

       对于size()的调用,其实是内联。在循环时,可以采用变量保存v.size()的值,以减少每个循环的调用开支。于是决定一搜,顺便总结之。

1、inline的引出

考虑下列min()函数

int min( int v1, int v2 )
{
  return( v1 < v2 << v1 : v2 );
}

      为这样的小操作定义一个函数的好处是:
     a.如果一段代码包含min()的调用,那阅读这样的代码并解释其含义比读一个条件操作符的实例,可读性会强很多。

     b.改变一个局部化的实现比更改一个应用中的300个出现要容易得多

     c.语义是统一的,每个测试都能保证相同的方式实现

     d.函数可以被重用,不必为其他的应用重写代码

     不过,将min()写成函数有一个严重的缺点:调用函数比直接计算条件操作符要慢很多。那怎么能兼顾以上优点和效率呢?C++提供的解决方案为inline(内联)函数

2、inline的原理:代码替代

       在程序编译时,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体来进行替代。

       例如,如果一个函数被指定为inline 函数则它将在程序中每个调用点上被内联地展开例如

int minVal2 = min( i, j );

在编译时被展开为

int minVal2 = i < j << i : j;

 则把min()写成函数的额外执行开销从而被消除了。
3、inline的使用

       让一个函数成为内联函数,隐式的为在类里定义函数,显式的则是在函数前加上inline关键字说明。

4、使用inline的一些注意事项

      a.从inline的原理,我们可以看出,inline的原理,是用空间换取时间的做法,是以代码膨胀(复制)为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。所以,如果函数体代码过长或者函数体重有循环语句,if语句或switch语句或递归时,不宜用内联

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

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

以上代码不能成为内联函数,而以下则可以

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

       所以说,inline 是一种“用于实现的关键字”,而不是一种“用于声明的关键字”。对于以上例子,林锐还建议,只在定义前加上inline,而不是在声明和定义前都加,因为这能体现高质量C++/C 程序设计风格的一个基本原则:声明与定义不可混为一谈。
       c.inline对于编译器来说只是一个建议,编译器可以选择忽略该建议。换句话说,哪怕真的写成了inline,也没有任何错误的情况下,编译器会自动进行优化。所以当inline中出现了递归,循环,或过多代码时,编译器自动无视inline声明,同样作为普通函数调用。

总结下:

       觉得可以将内联理解为C++中对于函数专有的宏,对于C的函数宏的一种改进。对于常量宏,C++提供const替代;而对于函数宏,C++提供的方案则是inline。在C中,大家都知道宏的优势,编译器通过复制宏代码的方式,省去了参数压栈,生成汇编的call调用,返回参数等操作,虽然存在一些安全隐患,但在效率上,还是很可取的。
       不过函数宏还是有不少缺陷的,主要有以下:

       a.在复制代码时,容易出现一想不到的边际效应,比如经典的

#define MAX(a, b) (a) > (b) ? (a) : (b)

在执行语句:

result = MAX(i, j) + 2 ;

时,会被解释为

result = (i) > (j) ? (i) : (j) + 2 ;

     b.使用宏,无法进行调试,虽然windows提供了ASSERT宏
     c.使用宏,无法访问类的私有成员
      所以,C++ 通过内联机制,既具备宏代码的效率,又增加了安全性,还可以自由操作类的数据成员,算是一个比较完美的解决方案。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索c++
内联函数
编程语言变量的理解、c语言内联函数、c语言有内联函数吗、易语言如何内联函数、c语言编程软件,以便于您获取更多的相关知识。

时间: 2024-11-03 20:06:20

C++编程中队内联函数的理解和使用_C 语言的相关文章

c++内联函数(inline)使用详解_C 语言

介绍内联函数之前,有必要介绍一下预处理宏.内联函数的功能和预处理宏的功能相似.相信大家都用过预处理宏,我们会经常定义一些宏,如 复制代码 代码如下: #define TABLE_COMP(x) ((x)>0?(x):0) 就定义了一个宏. 为什么要使用宏呢?因为函数的调用必须要将程序执行的顺序转移到函数所存放在内存中的某个地址,将函数的程序内容执行完后,再返回到转去执行该函数前的地方.这种转移操作要求在转去执行前要保存现场并记忆执行的地址,转回后要恢复现场,并按原来保存地址继续执行.因此,函数调

C++编程中将引用类型作为函数参数的方法指南_C 语言

有了变量名,为什么还需要一个别名呢?C++之所以增加引用类型, 主要是把它作为函数参数,以扩充函数传递数据的功能. 到目前为止我们介绍过函数参数传递的两种情况. 1) 将变量名作为实参和形参 这时传给形参的是变量的值,传递是单向的.如果在执行函数期间形参的值发生变化,并不传回给实参.因为在调用函数时,形参和实参不是同一个存储单元. [例]要求将变量i和j的值互换.下面的程序无法实现此要求. #include <iostream> using namespace std; int main( )

实例讲解C++编程中的虚函数与虚基类_C 语言

虚函数① #include "stdafx.h" #include <iostream> using namespace std; class B0//基类B0声明 { public: void display(){cout<<"B0::display()"<<endl;}//公有成员函数 }; class B1: public B0//公有派生类B1声明 { public: void display(){cout<<

深入探讨:宏、内联函数与普通函数的区别_C 语言

内联函数的执行过程与带参数宏定义很相似,但参数的处理不同.带参数的宏定义并不对参数进行运算,而是直接替换:内联函数首先是函数,这就意味着函数的很多性质都适用于内联函数,即内联函数先把参数表达式进行运算求值,然后把表达式的值传递给形式参数.    内联函数与带参数宏定义的另一个区别是,内联函数的参数类型和返回值类型在声明中都有明确的指定:而带参数宏定义的参数没有类型的概念,只有在宏展开以后,才由编译器检查语法,这就存在很多的安全隐患.    使用内联函数时,应注意以下问题:    1)内联函数的定

C++中内联函数的定义和使用

引入内联函数的目的是为了解决程序中函数调用的效率问题. 函数是一种更高级的抽象.它的引入使得编程者只关心函数的功能和使用方 法,而不必关心函数功能的具体实现:函数的引入可以减少程序的目标代码,实 现程序代码和数据的共享.但是,函数调用也会带来降低效率的问题,因为调用 函数实际上将程序执行顺序转移到函数所存放在内存中某个地址,将函数的程序 内容执行完后,再返回到转去执行该函数前的地方.这种转移操作要求在转去前 要保护现场并记忆执行的地址,转回后先要恢复现场,并按原来保存地址继续执 行.因此,函数调

如何调试C/C++内联函数及过程

这篇文章描述了一种持续的权衡方法,可以在调试程序和使之运行 更快之间取得正确的平衡.这篇文章同时还描述了如何调试内联函数及过程. 编写一个运行得快的程序并不容易.编译器可以帮助将一个程序转换成运行得更加快,但权衡是转换之后的程序与初始的程序会有所不同.在某些作了积极优化转换(aggressive optimization transform)的情形里,从人类的角度看转换后的程序与初始程序相比较已经几乎没有可读的一致性了. 因此,调试有问题的已优化程序会更加困难.这是一个问题,因为为了获得最大化的

详解C++中的内联函数和函数重载_C 语言

内联函数(内嵌函数,内置函数) 调用函数时需要一定的时间和空间的开销.C++提供一种提高效率的方法,即在编译时将函数调用处用函数体替换,类似于C语言中的宏展开.这种在函数调用处直接嵌入函数体的函数称为内联函数(inline function),又称内嵌函数或内嵌函数. 指定内联函数的方法很简单,只需要在定义函数时增加 inline 关键字. 注意:是在函数定义时增加 inline 关键字,而不是在函数声明时.在函数声明时增加 inline 关键虽然没有错误,但是也没有任何效果 inline 关键

C++文件头,命名空间,new和delete,内联函数,引用,函数重载,构造函数和析构函数,深拷贝和浅拷贝,explict,this指针

   目  录 1       开始学习C++.............................................................................................................. 4 1.1       C++的头文件...............................................................................................

C语言中的内联函数(inline)与宏定义(#define)详细解析_C 语言

先简明扼要,说下关键:1.内联函数在可读性方面与函数是相同的,而在编译时是将函数直接嵌入调用程序的主体,省去了调用/返回指令,这样在运行时速度更快. 2.内联函数可以调试,而宏定义是不可以调试的.内联函数与宏本质上是两个不同的概念如果程序编写者对于既要求快速,又要求可读的情况下,则应该将函数冠以inline.下面详细介绍一下探讨一下内联函数与宏定义. 一.内联函数是什么?内联函数是代码被插入到调用者代码处的函数.如同 #define 宏(但并不等同,原因见下文),内联函数通过避免被调用的开销来提