一般来说,调用一个函数流程为:当前调用命令的地址被保存下来,程序流跳转到所调用的函数并执行该函数,最后跳转回之前所保存的命令地址。

对于需要经常调用的小函数来说,这大大降低了程序运行效率。所以,C99 新增了内联函数(inline function)。

关键字 inline 告诉编译器,任何地方只要调用内联函数,就直接把该函数的机器码插入到调用它的地方。这样程序执行更有效率,就好像将内联函数中的语句直接插入到了源代码文件中需要调用该函数的地方一样。

要将一个函数定义为内联函数,需要在函数定义时加上 inline 函数修饰符。例 1 中,swapf()被定义为内联函数,用来交换两个浮点变量的值,函数 selection_sortf()会调用内联函数 swapf()。

【例1】函数 swapf()

// 函数swapf()交换两个浮点变量的值 // 参数:两个指向float的指针 // 返回值:无 inline void swapf( float *p1, float *p2 ) // 一个内联函数 { float tmp = *p1; *p1 = *p2; *p2 = tmp; } // 函数selection_sortf() 使用 selection-sort算法 // 对float数组进行排序 // 参数:一个float数组,以及其长度 // 返回值:无 void selection_sortf( float a[], int n ) // 对长度为n的数组进行排序 { register int i, j, mini; // 3个索引变量 for ( i = 0; i < n - 1; ++i ) { mini = i; // 从索引i开始,寻找最小值 for ( j = i+1; j < n; ++j ) if ( a[j] < a[mini] ) mini = j; swapf( a+i, a+mini); // 交换最小值元素和索引i元素的值 } }

一般来说,不建议把将包含循环的函数定义成内联函数,例如函数 selection_sortf()。例 1 在 for 循环中使用内联函数来加速执行效率。

inline 修饰符并非强制性的:编译器有可能会置之不理。例如,递归函数通常不会被编译成内联函数。编译器有权自行决定是否要将有 inline 修饰符的函数编译成内联函数。

和其他函数不同的是,在每个用到内联函数的翻译单元中,都必须重复定义这个内联函数。编译器必须时刻准备好该函数定义,以便在调用它时及时插入内联代码。因此,经常在头文件中定义内联函数。

如果某个翻译单元内的某个函数的所有声明都具有 inline 修饰符,而没有 extern 修饰符,那么该函数具有内联定义(inline definition)。

内联定义只针对翻译单元,它不构成外部定义,因此别的翻译单元可以包含该函数的外部定义。如果有外部定义附加到内联定义中,那么编译器可以自由选择要使用哪一种定义。

如果使用存储类修饰符 extern 来声明一个采用 inline 定义的函数,那么该函数的定义就会是外部的(external)。例如,下面的声明与 swapf()的定义如果放在例 1 的同一个翻译单元中,那么 swapf()就具有 extern 定义:

extern void swapf( float *p1, float *p2 );

一旦函数 swapf()具有外部的定义,其他翻译单元只需要采用普通的函数声明,就可以调用它。然而,从别的翻译单元调用函数,将不会被编译成内联函数。

内联函数其实就是普通函数,只不过它们在调用时采用机器码形式。和普通函数一样,内联函数具有自己的地址。如果内联函数使用到宏,预处理器就会展开宏,展开时所用的宏值,取该内联函数在源代码中定义所在位置的宏值。然而,在没被声明为 static 的内联函数中,不应该以静态存储周期的方式来定义可修改的对象。

c语言内联函数的声明,C语言内联函数相关推荐

  1. 在c语言中怎么返回引用参数,C语言函数 函数的声明 C语言的头文件 #include的用法 形参和实参 函数的返回值 - 猫扑天空...

    C语言函数 一.是什么? 是指编程中对一块功能代码的封装,可以理解一个程序片段 二.有什么用? 可以封装代码,方便调用,提高复用性 三.怎么用? 定义:  返回值类型  函数名(形参类型 参数名1-. ...

  2. c语言 函数的声明,C语言中的函数声明

    看了C陷阱与缺陷,第一个给我震撼的就是理解函数声明了,下面是我的理解. 1.理解函数声明 为了模拟开机启动时的情形,我们必须设计出一个C语句,以显示调用位于地址0的子例程.调用语句如下: (*(voi ...

  3. C语言的结构体前置声明,?C语言的不完整类型和前置声明

    声明与定义(Declaration and Definition) 开始这篇文章之前,我们先弄懂变量的declaration和definition的区别,即变量的声明和定义的区别. 一般情况下,我们这 ...

  4. 【C++之函数】引用符号、内联函数inline、函数重载

    文章目录 引用(&)是标识符的别名 内联函数(关键字:inline) 函数重载 引用(&)是标识符的别名 声明一个引用指向一个对象,则只是为对象的别名,其本身同所指对象保持一致. 例如 ...

  5. Go语言实践[回顾]教程23--详解Go语言函数的声明、变参、参数传递

    Go语言实践[回顾]教程23--详解Go语言函数的声明.变参.参数传递 函数的声明(定义) 函数的基本声明格式与调用 函数的变参(不定参) 值传递还是引用地址传递   函数是 Go 语言源代码的基本构 ...

  6. 【C语言-函数的声明与定义】

    [转载] 深入浅出,给初学者的难得的好文章 --- 一.函数的声明 1.在C语言中,函数的定义顺序是有讲究的:默认情况下,只有后面定义的函数才可以调用前面定义过的函数 1 int sum(int a, ...

  7. 【C语言】函数的声明_函数定义_函数调用_函数递归 [函数的基本使用]

    文章目录 前言 1.函数是什么? 2.C语言中函数的分类 2.1 库函数 2.2 自定义函数 3.函数的参数 3.1 实际参数(实参): 3.2 形式参数(形参): 4.函数的调用 4.1 传值调用 ...

  8. 【C语言】函数的理解——关于函数的声明

    函数的理解--关于函数的声明 #include <stdio.h> //void sumx(int begin,int end);//函数的声明 void sumx(int ,int ) ...

  9. 类的数据,成员函数,声明

    类的数据成员 在类中声明数据成员 类的数据成员的声明类似于普通变量的声明.如果一个类具有多个同一类型的数据成员,则这些成员可以在一个成员声明中指定. class Cube { //Cube类表示立方体 ...

最新文章

  1. 查看oracle当前消耗,查找Oracle高消耗语句的方法
  2. pytorch下载时出现错误:EOFError: Compressed file ended before the end-of-stream marker was reached
  3. matlab 蜂窝网格,blender怎么制作蜂巢网格 蜂窝式网格画法
  4. HBase读写流程、flush、文件合并、region拆分
  5. 255.255.255.255代表什么_LCD 党的真香警告?最近各家炒得很火的 DC 和 PWM 调光是什么鬼...
  6. Linux下多线程模拟停车场停车
  7. 如何开展软件架构之概念架构
  8. notepad可以运行python吗,notepad+中怎么设置直接运行python代码
  9. IOS开发中--点击imageView上的Button没有任何反应
  10. 漫画:有趣的 “切蛋糕“ 问题
  11. SSL-ZYC 2416 条形图
  12. 数字孪生智慧监狱三维可视化系统建设方案
  13. Teamviewer QuickSupport - 在电脑上远程连接控制手机/平板的软件神器 (Android/iOS)
  14. SQL SERVER数据库三种数据插入方式
  15. Xcopy 复制文件和目录,包括子目录。
  16. SPSS进行问卷数据的效度分析及结果解读(问卷数据统计分析第3步(转载)
  17. Linux课程设计每日小结
  18. 饭菜先生推出首款可随心定制的电子菜谱
  19. c语言atol是什么缩写,C语言atol函数的可移植版本疑问
  20. 水仙花数(c语言程序实现)

热门文章

  1. Clickhouse创建用户
  2. 瘦腿的三个黄金时间点
  3. nginx反向代理配置以及部署
  4. java语言中,一个汉字是几个字符?
  5. lovelive服务器维护,《Lovelive!》国服2周年庆典活动第五次开启
  6. 中华巡游 | 第十二届第⑤天:斗力频催鼓,争都更上筹
  7. Mint建站指北其之终 终篇 吹响吧上低音号
  8. Andorid BluetoothSocket的工作原理之二
  9. input输入框赋值、取值
  10. Java知识点思维导图