C++学习记录(四)——内联

有关宏定义的缺陷

宏的缺陷:

1. 仅仅是作一个简单的替换,编译器并不知道宏定义这回事。
2. 宏定义的没有做用域,须要手动卸载
3. 因为C++中预处理器不能访问雷内,因此宏定义不能成为类内函数c++

举一个简单的例子:
#define SQUARE(X) X*X//定义一个计算平方的宏
这个并非经过传参数来实现的,只是简单的替换,因此:函数

a = SQUARE(5.0);
b = SQUARE(1.0 + 2.0);
c = SQUARE(c++);

结果就是:
a = 5.0*5.0
b = 1.0 + 2.0* 1.0 + 2.0
c = c++*c++
虽然,咱们能够#define SQUARE(X) ((X)*(X))来解决,可是这里仍然致命的问题:宏不能按值传递。即使使用新的定义,咱们仍然阻止不了c递增了两次。code

内联(inline)

内联函数和常规函数

二者在写法上没有区别。只需在常规函数的声明前加 inline 关键字便可。
二者区别在于C++编译器是如何将其组合到程序中的。从而也能理解为何说内联是为了提高C++程序效率所作的一项改进。内存

常规函数的调用

在进行常规函数调用时会使程序跳到另外一个地址(函数地址),并在函数结束时返回。具体来讲,执行到函数调用指令时,程序将函数调用后当即存储该指令的内存地址,并将函数参数复制到堆栈,跳转到编辑函数起点的内存单元,执行函数代码(若是有返回值的话,将其放入寄存器中),而后跳回到地址被保存的指令处。在这样反复横跳的同时必然形成了必定的开销。作用域

内联函数的调用

编译器将使用相应的函数代码替换函数调用。这样程序无需跳到另外一处去执行代码,而后在跳回来。虽然内联函数的运行速度比常规函数快,可是消耗了更多内存。这时候咱们便存在取舍:编译器

  • 若是执行代码的时间比处理函数调用的时间长,则所节省的时间不过只占整个过程的一小部分。
  • 若是代码执行时间很短则内联调用就能够节省非内联调用使用的绝大部分时间。(虽然节省了时间,可是时间的绝对值并不大)

因此,当你的函数内容短小,逻辑简单并且常常被调用,那么内联绝对是很是好的选择。编译

内联的使用

  • 函数声明前加 inline 关键字
  • 函数定义前加 inline 关键字

须要注意的是,知足如下条件中的任意一条的函数,编译器都不会作内联处理。效率

  • 存在任何形式的循环语句
  • 存在过多的条件语句
  • 函数体过于庞大
  • 对函数进行取地址操做

咱们发现一个事情:上述的4个条件中出现了很含糊的词语——“过于”。这使咱们不由想问,这个“过于庞大”,“过多”到底是一个什么标准?循环

没错!程序

其实,内联仅仅是给编译器的一个建议,编译器不必定接受你的建议。并且,就算你没有声明将函数声明为内联函数,编译器也可能作内联处理。因此,这里仅仅是单纯的讲述有内联这么一回事。~~~~

相关文章
相关标签/搜索