欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

内联函数与宏定义

程序员文章站 2024-03-21 10:18:10
...

http://blog.csdn.net/u011327981/article/details/50601800
内联函数与宏的差别是什么?
内联函数和普通函数相比可以加快程序运行的速度,因为不需要中断调用,在编译的时候内联函数可以直接被镶嵌到目标代码中。而宏只是一个简单的替换。
内联函数:
在c++中我们通常定义一下函数来求两个整数的最大值

int maxint a,int b)
{
return a>b?a:b;
}

为什么一个小小的操作定义一个函数的好处
1、阅读和理解函数max的调用,要比度一条等价的条件表达式并理解它的含义要容易很多。
2、如果要做修改,修改函数要比找出并修改每一处等价表达式要容易得多。
3、使用函数可以确保统一行为,每个测试都保证以相同的方式实现
4、函数可以重用,不必为其他应用程序重写代码
调用函数的缺点:
调用函数比丘戒等价表达式要慢很多。
调用函数要做的工作:1、调用前先要保存寄存器2、返回时恢复,3、复制实参,4、程序还必须转向一个新位置执行。
为什么要有内联函数
目的是为了提高函数的执行效率

inline int max(int a,int b)
{
return a>b?a:b;
}

则调用:cout<

#define MAX(a,b) (a)>(b)?(a):(b)
语句:
result=MAX(i,j)+2;
会被于处理器扩展为:
result=(i)>(j)?(i):(j)+2
如果把宏修改为
#define MAX(a,b) ((a)>(b)?(a):(b))可以解决优先级引起的错误

另外一个例子:
result=MAX(i++,j);
会被预处理器解释为
result=(i++)>(j)?(i++):(j);在同一个表达式中i被两次求值

2、不可调试(但是内联函数是可以调试的
为什么内联函数可以调试呢?
在程序的debug版本里面它根本就没有真正的内联,编译器像普通函数那样为它生成含有调试信息的可执行代码。在程序的发行(Release)版本里面,编译器才会实现真正的内联
3、
无法操作类的私有数据成员
内联函数是如何工作的?
对任何内联函数,编译器在符号表里面放入函数的声明,包括名字、参数类型、返回值类型。如果编译器没有发现内联函数存在错误,那么该代码也被放入符号表里。在调用内联函数时,编译器首先检查调用是否正确(进行类型安全检查、进行自动类型转换)如果正确,内联函数的代码就会直接替换函数调用语句。
预处理器不能进行类型安全检查和自动类型转换,内联函数如果是成员函数,对象的指针会被放在和是的地方,这也是与处理器办不到的
结论
在C++中应该用内联函数来取代宏代码。assert’是一个例外,assert是仅仅在debug版本起作用的宏,为了不再debug和release有差别,则应该用宏定义。

如果assert是函数,由于函数调用会引起内存,代码的变动,会使debug与release产生差别。

另外一个优点:
函数被内联后,编译器可以通过上下文相关的优化技术对结果代码执行更深入的优化。
慎用内联:
内联可以省去函数调用的开销。从而提高程序的执行效率。
这里所说的函数调用所需要的开销:参数压栈、跳转、退栈、返回惭怍。加入执行函数体内代码的时间比函数调用的开销大得多,则inline的效率会很小。另外每一处都需要拷贝代码,使得程序的总代码量增加,消耗更多的内存空间。

不宜用内联的情况:
1、如果函数体内的代码比较长,使用内联将导致代码膨胀过大。
如果函数体内出现循环或者其他的复杂结构,那么值型函数体代码的时间将比函数调用的开销大很多。
若把类的成员函数或者析构函数变为内联函数:
但是构造函数和内联函数会隐藏一些行为:如调用基类或者成员对象的构造函数或者析构函数。所以不要轻易让构造函数和析构函数称为内联函数。

相关标签: c语言