‘壹’ 关于C语言,内联函数有什么优点
引入内联函数的目的是为了解决程序中函数调用的效率问题。
函数是一种更高级的抽象。它的引入使得编程者只关心函数的功能和使用方法,而不必关心函数功能的具体实现;函数的引入可以减少程序的目标代码,实现程序代码和数据的共享。但是,函数调用也会带来降低效率的问题,因为调用函数实际上将程序执行顺序转移到函数所存放在内存中某个地址,将函数的程序内容执行完后,再返回到转去执行该函数前的地方。这种转移操作要求在转去前要保护现场并记忆执行的地址,转回后先要恢复现场,并按原来保存地址继续执行。因此,函数调用要有一定的时间和空间方面的开销,于是将影响其效率。特别是对于一些函数体代码不是很大,但又频繁地被调用的函数来讲,解决其效率问题更为重要。引入内联函数实际上就是为了解决这一问题。
在程序编译时,编译器将程序中出现的内联函数的调用表达式用内联函数的函数体来进行替换。显然,这种做法不会产生转去转回的问题,但是由于在编译时将函数休中的代码被替代到程序中,因此会增加目标程序代码量,进而增加空间开销,而在时间代销上不象函数调用时那么大,可见它是以目标代码的增加为代价来换取时间的节省。
‘贰’ 有内联函数被编译为dll,内联是否失效
1. inline 关键字, 只是建议编译器按内联处理, 编译器不一定将该函数按内联处理。
2. 内联函数不是真正意义的函数。 它不会被编译成函数, 也就不会在编译成的dll中。 你可以把内联函数理解成具有类型检查功能的宏。
3. 使用内联函数,需要包含其实现代码(函数体), 因此一般都将其函数体写在头文件中。 如果不这么做, 当你在其他模块中调用该内联函数时, 你将面临麻烦。 你就必须要包含内联函数体所在的文件(.cpp )文件。
表述也许不太清楚, 有问题可以email:[email protected]
‘叁’ 内联函数可以有条件运算符做判断吗那样编译器会不会编译为普通函数
可以
内联函数的原则是:
1.代码尽量简单
2.不要出现循环、递归
多数编译器并不把带有循环、等或者代码比较多的函数进行内联编译
‘肆’ 内联函数的定义对编译器而言必须是可见的什么意思
解答其实已经说得很清楚了,编译器在看到程序中调用普通函数的代码时,是在这里填一个函数的地址,然后在执行时跳转到函数那边去。而碰到内联函数时,是将函数的内容全部在调用点展开,所以它必须知道这个内联函数的定义是什么,否则无法展开。而将内联函数的定义放在头文件(.h)中,一旦include了该头文件,就能看到内联函数的全部内容了,也就可以在调用点完全展开内联函数。如果将内联函数放在源文件中(.c),编译器在看到内联函数的调用时,是无法知道内联函数的内容的,因此也无法展开,所以必须将内联函数定义在头文件中。
‘伍’ 内联函数在编译时是否做参数类型检查
这是必须滴啊。
‘陆’ 内联函数在编译时是否作参数类型检查
现在你不必理会这些东西。现在的CPU很智能的,只要你的语法不错误,内联和写在外面,不会有任何的区别。
‘柒’ 内联函数有什么作用,详细说明
内联函数准确的说,不是函数。编译器会在调用的地方,直接把函数体代码生成在那里。这样的好处是少了一次函数调用,节省了函数调用的开支(比如变量压栈,出栈,指针跳转)。
他像是宏展开,但不同的是,宏展开不会检查参数类别,内联函数还是会检查参数类别,这点表现的又像函数。
‘捌’ 在什么情况下适宜采用inline定义内联函数
使用高度频繁,而且操作内容简单的情况下,用inline函数。这样可以解决一些频繁调用的函数大量消耗栈空间(栈内存)的问题。关键字inline必须与函数定义放在一起才能使函数成为内联函数,仅仅将inline放在函数声明前面不起任何作用。inline是一种“用于实现”的关键字,而不是一种“用于声明”的关键字。
inline定义格式
一、inline关键字用来定义一个类的内联函数,引入它的主要原因是用它替代C中表达式形式的宏定义。
表达式形式的宏定义如:
#define ExpressionName(Var1,Var2) ((Var1)+(Var2))*((Var1)-(Var2))
取代这种形式的原因如下:
1、C中使用define这种形式宏定义的原因是因为,C语言是一个效率很高的语言,这种宏定义在形式及使用上像一个函数,但它使用预处理器实现,没有了参数压栈,代码生成等一系列的操作。因此,效率很高,这是它在C中被使用的一个主要原因。
2、这种宏定义在形式上类似于一个函数,但在使用它时,仅仅只是做预处理器符号表中的简单替换,因此它不能进行参数有效性的检测,也就不能享受C++编译器严格类型检查的好处,另外它的返回值也不能被强制转换为可转换的合适的类型。这样,它的使用就存在着一系列的隐患和局限性。
3、在C++中引入了类及类的访问控制,这样,如果一个操作或者说一个表达式涉及到类的保护成员或私有成员,你就不可能使用这种宏定义来实现(因为无法将this指针放在合适的位置)。
4、inline推出的目的,也正是为了取代这种表达式形式的宏定义,它消除了宏定义的缺点,同时又很好地继承了宏定义的优点。
(8)内联函数编译时会检查正确性吗扩展阅读
内联函数的不足
除了通常使用内联扩展可能带来的问题,作为一种编程语言特性的内联函数也可能并没有看起来那么有效,原因如下:
1、通常,设计编译器的程序设计者比大多数的程序设计者更清楚对于一个特定的函数是否合适进行内联扩展;一些情况下,对于程序员指定的某些内联函数,编译器可能更倾向于不使用内联甚至根本无法完成内联。
2、对于一些开发中的函数,它们可能从原来的不适合内联扩展变得适合或者倒过来。尽管内联函数或者非内联函数的转换易于宏的转换,但增加的维护开支还是使得它的优点显得更不突出了。
3、对于基于C的编译系统,内联函数的使用可能大大增加编译时间,因为每个调用该函数的地方都需要替换成函数体,代码量的增加也同时带来了潜在的编译时间的增加。
参考资料来源:网络-内联函数
参考资料来源:网络-inline
‘玖’ C++内联函数在 在编译时是将该函数的目标代码插入每个调用该函数的地方
内联函数在调用时,是将调用表达式用内联函数体来替换,而一般函数进行调用时,要将程序执行权转到被调用函数中,然后再返回到调用它的函数中。
如果内联失败这个函数就是一个普通的函数,普通的函数不会被编译器展开,只是作为函数调用。内联函数比普通函数效率高的原因就是编译器在调用处把这个函数展开,展开就是直接执行代码而不是调用这个函数,像宏展开的意思。
(9)内联函数编译时会检查正确性吗扩展阅读:
宏调用并不执行类型检查,甚至连正常参数也不检查,但是函数调用却要检查。C语言的宏使用的是文本替换,可能导致无法预料的后果,因为需要重新计算参数和操作顺序。在宏中的编译错误很难发现,因为它们引用的是扩展的代码,而不是程序员键入的。
许多结构体使用宏或者使用不同的语法来表达很难理解。内联函数使用与普通函数相同的语言,可以随意的内联和不内联。
‘拾’ C++中的内联函数是在编译时原地展开的还是在运行时原地展开的
编译时就确定了调用次数的 所以是编译器就展开