首页 >  知识中心 >  新闻详情

内联函数是在预处理 内联函数和编译预处理的区别是?

来源:朵拉利品网  |  2019-07-24 20:23:59

1, 内联函数和编译预处理的区别是?



预处理只是一种简单替代,内联函数比较安全,编译器会自动判断是否可以内联等。
用#define预处理的时候会有一些副作用
比如:
#define ADD(x) (x+1)*(x+1)
如果有代码想要先做a++,再做ADD,那可能就会有问题
ADD(a++)就成了((a++)+1)*((a++)+1)
然而用内联函数就没有问题
所以很多人推荐尽量用内联函数来代替这种预处理
而用const来代替那些预处理的常量定义
但是预处理也有很多inline实现不了的功能,看一下MFC中大量的宏就可以看到它强大的功能。

2, 内联函数是什么?



定义:
内联函数从源代码层看,有函数的结构,而在编译后,却不具备函数的性质。内联函数不是在调用时发生控制转移,而是在编译时将函数体嵌入在每一个调用处。编译时,类似宏替换,使用函数体替换调用处的函数名。一般在代码中用inline修饰,但是能否形成内联函数,需要看编译器对该函数定义的具体处理。
简介:
“一个函数声明[。。。]说明符声明一个内联与内联函数。内联说明符指示的实现,内联函数体替代了在调用点是首选通常的函数调用机制。一个实现不要求在调用执行此点内联替代,但是,即使这个内嵌替代省略,由7.1.2内联函数定义的其他规则,仍应得到尊重“。
注意事项:
内联函数具有一般函数的特性,它与一般函数所不同之处只在于函数调用的处理。一般函数进行调用时,要将程序执行权转到被调用函数中,然后再返回到调用它的函数中;而内联函数在调用时,是将调用表达式用内联函数体来替换。在使用内联函数时,应注意如下几点:
1. 在内联函数内不允许用循环语句和开关语句。 如果内联函数有这些语句,则编译将该函数视同普通函数那样产生函数调用代码,递归函数(自己调用自己的函数)是不能被用来做内联函数的。内联函数只适合于只有1~5行的小函数。对一个含有许多语句的大函数,函数调用和返回的开销相对来说微不足道,所以也没有必要用内联函数实现。
2. 内联函数的定义必须出现在内联函数第一次被调用之前。
3. 本栏目讲到的类结构中所有在类说明内部定义的函数是内联函数。

3, 内联函数是作什么用的?



普通函数在调用的时候,会经过
压栈
跳转
运行
弹栈
这几步操作,其中压栈,跳转,弹栈都增加了额外的开销。
而内联函数的函数体直接在调用的地方展开,省去了上面这三步。
如果你的函数体语句不多,并且会频繁的被调用,那么就用内联吧。
从内联的展开特性上来看,它与宏定义很相似,除此之外它还提供了宏定义锁没有的类型检查,可以带返回值以及方便调试的特性。

5, 什么是内联函数



楼主有意思,我觉得楼上的答案已经够“官方”的了么...
内联函数就是小型函数,牺牲空间来节省函数调用的开销,一般用作比较小的函数,即函数内部没有循环、开关语句等。内联函数被发明出来就是为了取代C中的宏,因为宏是单纯的替换而没有类型检查所以经常出毛病,比如:
#define MAX(a, b) (a) > (b) ? (a) : (b)
如果你在代码中这样写:
int a = 5, b = 10;
// int max = MAX(++a, b); // a自增了两次
// int max = MAX(++a, b+10); // a自增了一次
a的自增次数竟然由与其比较的数字的大小来决定!?这肯定不是你想要的结果。
所以最好的办法是这样:
template <class T>
inline T max(const T& t1, const T& t2)
{
return t1 > t2 ? t1 : t2;
}
这样的话如果你这样写:
int max = max(a, b);
其实就被替换为了:
int max = a > b ? a : b;
虽然看起来宏差不多,但是比宏多了类型检查,而且内联函数使用的是真正的函数的特性,而不是宏的function-like,模拟函数的功用。
内联函数是为频繁使用、并且过程不大的小型函数设计的,我说了它是以牺牲代码空间来节省函数调用的开销,内联函数使用不当就会造成代码膨胀,所以使用它一定要小心。
建议(书上抄的):
For function-like macros, prefer inline functions to #defines.
楼主有时间还是多看看书好,这里毕竟专家不多,而且也没多少人有太多的时间和精力来帮你解决这些基础性的问题,好好地读几本书吧,一定会让你获益匪浅的...

6, 内联函数与普通函数的区别是什么



内联函数是代码被插入到调用者代码处的函数。如同 #define 宏,内联函数通过避免被调用的开销来提高执行效率,尤其是它能够通过调用(“过程化集成”)被编译器优化。
内联函数和宏很类似,而区别在于,宏是由预处理器对宏进行替代,而内联函数是通过编译器控制来实现的。而且内联函数是真正的函数,只是在需要用到的时候,内联函数像宏一样的展开,所以取消了函数的参数压栈,减少了调用的开销。你可以象调用函数一样来调用内联函数,而不必担心会产生于处理宏的一些问题。
声明内联函数看上去和普通函数非常相似:
void f(int i, char c);
当你定义一个内联函数时,在函数定义前加上 inline 关键字,并且将定义放入头文件:
inline void f(int i, char c) { // ... }
任何在类的说明部分定义的函数都会被自动的认为是内联函数。
内联函数必须是和函数体申明在一起,才有效。像这样的申明Inline Tablefunction(int I)是没有效果的,编译器只是把函数作为普通的函数申明,我们必须定义函数体。
Inline tablefunction(int I) {return I*I};
这样我们才算定义了一个内联函数。我们可以把它作为一般的函数一样调用。但是执行速度确比一般函数的执行速度要快。
我们也可以将定义在类的外部的函数定义为内联函数,比如:
Class TableClass{ Private: Int I,j; Public: Int add() { return I+j;}; Inline int dec() { return I-j;} Int GetNum(); } inline int tableclass::GetNum(){ return I; }
上面申明的三个函数都是内联函数。在C++中,在类的内部定义了函数体的函数,被默认为是内联函数。而不管你是否有inline关键字。
内联函数在C++类中,应用最广的,应该是用来定义存取函数。我们定义的类中一般会把数据成员定义成私有的或者保护的,这样,外界就不能直接读写我们类成员的数据了。对于私有或者保护成员的读写就必须使用成员接口函数来进行。如果我们把这些读写成员函数定义成内联函数的话,将会获得比较好的效率。
Class sample{ Private: Int nTest; Public: Int readtest(){ return nTest;} Void settest(int I) {nTest=I;} }
当然,内联函数也有一定的局限性。就是函数中的执行代码不能太多了,如果,内联函数的函数体过大,一般的编译器会放弃内联方式,而采用普通的方式调用函数。这样,内联函数就和普通函数执行效率一样了。

相关概念


预处理

预处理(pre-treatment),是指在进行最后加工完善以前进行的准备过程,具体应用在不同的行业或领域,会有不同的解释。在一些程序设计语言中,预处理是preprocessing的翻译。

++

"++"是C和C++里的自增运算符,使可变左值(如变量,迭代器变量等)加一。 用法主要有两种: i++ ++i

 
相关新闻
内联函数的好处与不足 内联函数作用是? 07-24
内联函数与外联函数的区别 内联函数和外联函数有什么区别 07-24
内联函数定义 内联函数是什么? 07-24
内联函数何时使用 c++什么时候需要使用内联函数? 07-24
内联函数是什么 内联函数是什么? 07-24
什么时候使用内联函数 c++什么时候需要使用内联函数? 07-24
内联函数的关键字为 内联函数与普通函数的区别是什么 07-24
区分内联函数 内联函数与普通函数的区别是什么 07-24
内联函数是在预处理 内联函数和编译预处理的区别是? 07-24
内联函数与重载函数 内联函数和 普通函数 宏定义的区别 07-24
相关产品
氨制冷设备配件螺杆机专用联轴器 联轴器膜片 压缩机配件联轴器 05-15
供应 LWG-3080 频率信号发生器 函数信号源 脉冲群发生器 05-21
厂家供应 太阳能工程联箱 太阳能工程联箱厂家 价格优惠 值得选购 06-01
铝合金联轴器 06-15
生物质颗粒燃炉预处理降温旋风除尘器 单管旋风除尘器厂家直销 06-21
温州仓库笼,仓库笼规格图,联鑫源 06-22
滚筒减速机连接部件 联轴器 减速机配套联轴器 清江减速机联轴器 06-30
联讯柴油发电机零配件中心 08-23
废旧编织袋液压铡刀 鼎联 铡刀 现货报价 08-28
供应亚临界萃取沙棘籽油加工设备成套生产线预处理亚临界萃取精炼 09-18

大家都在看