您的位置:首页 > 其它

第16章 C预处理器和C库 16.7 内联函数

2017-07-26 00:00 134 查看
通常函数调用需要一定的时间开销。这意味着执行调用时花费了时间用于建立调用、传递参数、跳转到函数代码段并返回。使用类函数宏的一个原因就是减少执行时间。C99还提供了另一种方法:内联函数(inline function)。

C99这样叙述:把函数变成内联函数将建议编译器尽可能快速地调用该函数。上述建议的效果由实现来定义。因此,使函数变为内联函数可能会简化函数的调用机制,但也可能不起作用。

创建内联函数的方法是在函数声明中使用函数说明符inline。通常,首次使用内联函数前在文件中对该函数进行定义。因此该定义也作为函数原型。也就是说代码应像下面这样:

#include <stdio.h>
inline void eatline()  //内联函数的定义/原型
{
while(getchar()!='\n')
continue;
}
int main()
{
...
eatline();  //函数调用
...
}

编译器看到内联声明后会用eatline()函数体代替函数调用,其效果如果您在此处键入了函数体的代码。

因为内联函数没有预留给它的单独的代码块,所以无法获得内联函数的地址。(实际上可以获得地址,但这样会使编译器产生非内联函数)。另外,内联函数不会在调试器中显示。

内联函数应该比较短小。对于很长的函数,调用函数的时间少于执行函数主体的时间;此时,使用内联函数不会节省多少时间。

编译器在优化内联函数时,必须知道函数定义的内容。这意味着内联函数的定义和对该函数的调用必须在同一文件中。正因为这样,内联函数通常具有内部链接;因此,在多文件程序中,每个调用内联函数的文件都要对该函数进行定义。达到这个目标的最简单方法:在头文件中定义内联函数,并在使用该函数的文件中包含该头文件。一般不在头文件中放置可执行的代码,但内联函数是个例外。因为内联函数具有内部链接,所在在多个文件中定义同一内联函数不会产生什么问题。

C提供了几种方法用于在多文件程序中使用内联函数。通常,C只允许对函数进行惟一的一次定义,但是对内联函数却放松了这个原则。因此,最简单的方法是在使用内联函数的文件中都定义该函数要达到这一目标的最简单方式为:在头文件中定义内联函数并在使用该函数的源代码文件中包含该头文件。

与C++不同的是,C允许混合使用内联函数定义和外部函数定义(具有外部链接的函数定义)。例如,考虑下面的设置:

//file1a.c
...
inline double square(double);
double square(double x){return x*x;}
int main()
{
double q = square(1.3);
...
//file2a.c
...
extern double square (double);
double square (double x){int y; y=x*x; return y;}
void spam(double v)
{
double kv = square(v);
...
//file3a.c
...
extern double square(double);
void masp(double w)
{
double kw = square(w);
...

这里file1a.c使用file1a.c中定义的内联函数square( )。但是,file2a.c和file3a.c则使用file2a.c中的外部函数定义。

C甚至还允许在包含内联函数定义的文件中放置外部函数声明:

//file1b.c  --小心!
...
extern double square(double);  //把square()声明为外部函数
inline double square(double);  //把square()声明为内联函数
double square(double x){ return x*x;}

int main(void)
{
double q = square(1.3)+square(1.5);    //哪一个square()?
...
//file2b.c
...
extern double square(double);
double square(double x){int y; y=x*x; return y;}
...

此时,在file1b.c对square()的调用中,编译器可随意使用该函数的内部定义或外部定义。甚至再次调用所使用的定义可以不致。C标准警告程序员,不要编写依赖于所选函数版本的代码。前面提到,任何带有内联函数定义的文件使用获取该函数地址的代码后(例如,传递函数外作为实际参数),编译器都会产生外部函数定义。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  内联函数 inline extern