1、什么是内联函数?
在C语言中,如果一些函数被频繁调用,不断地有函数入栈,即函数栈,会造成栈空间或栈内存的大量消耗。为了解决这个问题,特别的引入了inline修饰符,表示为内联函数。
#include <stdio.h>
char* dbtest(int a);
//函数定义为inline即:内联函数
inline char* dbtest(int a)
{
return (a % 2 > 0) ? "奇" : "偶";
}
int main()
{
int i = 0;
for (i=0; i < 50; i++)
{
if (i%5 == 0)
printf("\n");
printf("i:%d 奇偶性:%s ", i, dbtest(i));
}
printf("\n");
}
2、内联函数和普通函数的区别
普通函数调用步骤
-
保存当前函数的上下文(包括寄存器状态、返回地址等)
-
将控制权转移到被调用函数的代码位置
-
执行被调用函数的代码
-
恢复上下文并返回
内联函数调用步骤
将内联函数的代码直接插入到每个调用点
3、内联函数和宏定义的区别
| 比较点 | 宏定义 | 内联函数 |
| 处理阶段 | 预处理阶段将宏调用替换为宏定义中的代码 | 编译阶段的代码展开 |
| 是否有语法检查 |
不检查
|
语法检查和函数参数类型检查
|
| 调试和维护 | 预处理阶段被展开,调试时无法看到宏的定义 | 调试时可以像普通函数一样设置断点和查看变量 |
|
性能 |
宏定义是简单的文本替换,不会增加额外的函数调用开销 宏定义较大且调用频繁时,可能导致代码膨胀 |
可以减少函数调用的开销 内联函数复杂的话,编译器通常会进行优化以避免过度膨胀 |
|
适用情形 |
适用于简单的文本替换,如常量定义、简单的表达式
|
适用于需要类型检查和调试支持的简单函数 适用于函数体较小且调用频繁的场景
|
4、内联函数使用注意点
(1)内联函数不可递归
(2)函数内容太过于复杂,编译器会忽略inline关键字,把他当成普通函数来处理
(3)函数体较小且调用频繁的场景,需要类型安全和调试支持时使用内联函数
(4)建议inline函数的定义放在头文件中,避免每个源文件都定义一次
(5)关键字inline 必须与函数定义体放在一起才能使函数成为内联,仅将inline 放在函数声明前面不起任何作用
inline内联函数
浙公网安备 33010602011771号