一,什么是内联函数
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数压栈的开销, 内联函数提升程序运行的效率。
inline int square(int x) {
return x * x;
}
int main() {
int a = square(3);
int b = square(5);
}
编译后,编译器会把它 “展开” 成:
int main() {
int a = 3 * 3;
int b = 5 * 5;
}
没有函数调用,没有跳转,没有栈操作 → 速度更快。
普通函数为什么有开销?
当你调用一个普通函数时,CPU 要做这些事:
- 保存当前执行位置(返回地址)
- 把参数压入栈
- 跳转到函数地址执行
- 执行完再跳回来
- 恢复栈、恢复现场
这一套叫函数调用开销。
inline 告诉编译器:
这个函数很小、调用很频繁,别当成普通函数调用,直接把代码复制粘贴到调用的地方。
这就叫内联展开(inline expansion)。
二,inline 的本质
1,inline 是建议,不是命令
编译器有权拒绝:
- 函数太大
- 有循环、递归
- 虚函数、复杂逻辑
编译器会自动忽略 inline,当成普通函数。
只在编译期生效
运行时不存在 “内联” 这个概念,只有机器码。
内联≠宏
宏是文本替换,内联是真正的函数,有类型检查、作用域、语法检查。
三,内联函数的优缺点
优点
- 消除函数调用开销,提高执行速度
- 比宏安全,不会出现宏的奇怪副作用
- 代码结构清晰,可读性好
- 支持调试、类型安全
缺点
- 代码膨胀(二进制变大)
- 调用 100 次就复制 100 份函数体,程序体积变大
- 体积过大会导致 CPU 缓存命中率下降,反而更慢
- 编译变慢
- 调试困难(没有独立栈帧)
四,什么时候适合用 inline?
适合
- 函数体非常短(1~5 行)
- 高频调用(循环 millions 次)
- 简单 getter/setter
- 简单算术、比较函数
- 模板小函数
不适合
- 函数大
- 有循环、递归
- 虚函数(大部分情况不能内联)
- 调用不频繁的函数
- 复杂逻辑
声明与定义分离时inline 必须写在定义处,不能只写在声明。
// 头文件
void f();
// 源文件
inline void f() { ... }
五,inline 与 宏 #define 的核心区别
| 特性 | #define 宏 | inline 内联函数 |
|---|---|---|
| 处理阶段 | 预处理(文本替换) | 编译期 |
| 类型检查 | ❌ 无 | ✅ 严格检查 |
| 作用域 | 全局,容易冲突 | ✅ 有作用域 |
| 副作用 | 极易出现(如 #define S(x) x*x) | ✅ 无 |
| 调试 | 无法调试 | 可调试 |
| 递归 | 不支持 | 编译器可处理简单递归 |
inline是一种以空间换时间的做法,省去调用函数额开销。所以代码很长或者有循环/递归的函数不适宜 使用作为内联函数。
【思考题】
宏的优缺点?
优点:
1.增强代码的复用性。
2.提高性能。
缺点:
1.不方便调试宏。(因为预编译阶段进行了替换)
2.导致代码可读性差,可维护性差,容易误用。
3.没有类型安全的检查 。
C++有哪些技术替代宏?
1. 常量定义 换用const
2. 函数定义 换用内联函数
6万+

被折叠的 条评论
为什么被折叠?



