当前位置: 首页 > news >正文

内联函数——C++

内敛函数的定义:

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率

(它是以空间换取时间的方式提高效率,这里的空间指的是可执行程序的大小

没有加inline时,在release优化后执行时会调用(call)函数
在这里插入图片描述
加inline后,在release优化后直接展开,不会再调用,调用几次展开几次
在这里插入图片描述

特性

  1. inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率
    (比如函数体30行指令,需要调用1000次,没有inline下的指令数是1000+30行;有inline下的指令数是1000*30行,虽然少了栈帧的创建,但是可执行程序的空间变大)
  2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。下图为《C++prime》第五版关于inline的建议:
    在这里插入图片描述
    为什么代码长了不展开呢?
    展开后会使可执行程序大小变大。造成代码膨胀,不值得,编译器会自动识别函数长度再考虑要不要展开
  3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到
    (在编译期间,会生成符号表,符号表中存放着函数的地址,在其他文件中引.h文件中函数的声明时,只要符合调用的规则,在编译期间并不会去其他文件找到对应的定义并开始调用,而是会在链接的时候将所有文件函数定义合并到一个符号表上,再根据函数名来找到对应的地址进行调用,但是如果inline修饰后的函数,函数的地址是进入符号表中的,这个时候只有声明没有定义,会出现函数未定义的错误)
XXX.h
int Add(int x, int y);

XXX.cpp
#include "XXX.h"

int Add(int x, int y)
{
	return x + y;
}

test.cpp
#include <iostream>
#include "XXX.h"

using namespace std;

int main()
{
	int sum = Add(3, 4);
	cout << sum << endl;

	return 0;
}

在这里插入图片描述
所以直接把内联函数直接定义在.h头文件中,需要直接引入头文件,不要声明与定义分离

宏和内联函数

内联函数其实就是宏函数的优化后的产物,至于优化的地方就需要看一下宏的缺点

宏的缺点:
  1. 不方便调试宏。(因为预编译阶段进行了替换)
  2. 导致代码可读性差,可维护性差,容易误用
    正确:#define ADD(x,y) ((x)+(y))
    错误:#define ADD(x,y) (x+y)#define ADD(x,y) x+y#define ADD(x,y) ((x)+(y));
    对应使用ADD(1|0,1&1),ADD(2,3)*2,if(ADD(1,0));会出现符号优先级等问题
  3. 没有类型安全的检查
宏的优点:
  1. 增强代码的复用性
  2. 提高性能
在C++中有两种方法来优化宏的缺点
  1. 常量定义 换用const enum
  2. 短小函数定义 换用内联函数

相关文章:

  • 数据结构-线性表
  • vue3.0--2.watch、vue3生命周期函数、Teleport、自定义事件、状态驱动的动态 CSS、Suspense
  • Java · 面向对象编程 · 包的概念 · 继承 · 组合
  • Zabbix6通过ODBC方式监控Oracle 19C最佳实践
  • 企业复杂的数据治理需求,TempoDF让数据开发更简单!
  • hive on spark 执行sql报错
  • 离散化(保序)
  • 文本纠错易语言代码
  • 【python】遇上COS美图怎么办?当然是大胆冲呀~
  • 苏小妍java开发工程师-一面面经
  • 「SpringCloud Alibaba」Sentinel实现熔断与限流
  • 赶紧进来看看---详细介绍五种常用字符串库函数 以及对库函数的模拟实现
  • 浅谈 python在密码学的应用
  • lammps数据后处理:python绘制应力应变曲线 附程序代码
  • 机器学习模型2——决策树
  • docker python 配置
  • exif信息对照
  • Java知识点总结(JDBC-连接步骤及CRUD)
  • Laravel 中的一个后期静态绑定
  • maven工程打包jar以及java jar命令的classpath使用
  • Nodejs和JavaWeb协助开发
  • QQ浏览器x5内核的兼容性问题
  • unity如何实现一个固定宽度的orthagraphic相机
  • 彻底搞懂浏览器Event-loop
  • 分享一份非常强势的Android面试题
  • 搞机器学习要哪些技能
  • 猴子数据域名防封接口降低小说被封的风险
  • 开源中国专访:Chameleon原理首发,其它跨多端统一框架都是假的?
  • 如何将自己的网站分享到QQ空间,微信,微博等等
  • 使用Envoy 作Sidecar Proxy的微服务模式-4.Prometheus的指标收集
  • 微信小程序:实现悬浮返回和分享按钮
  • 源码之下无秘密 ── 做最好的 Netty 源码分析教程
  • 主流的CSS水平和垂直居中技术大全
  • 《天龙八部3D》Unity技术方案揭秘
  • 翻译 | The Principles of OOD 面向对象设计原则
  • 曜石科技宣布获得千万级天使轮投资,全方面布局电竞产业链 ...
  • # centos7下FFmpeg环境部署记录
  • #Linux(权限管理)
  • #我与Java虚拟机的故事#连载18:JAVA成长之路
  • $ is not function   和JQUERY 命名 冲突的解说 Jquer问题 (
  • (02)vite环境变量配置
  • (2022版)一套教程搞定k8s安装到实战 | RBAC
  • (Matalb时序预测)PSO-BP粒子群算法优化BP神经网络的多维时序回归预测
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (带教程)商业版SEO关键词按天计费系统:关键词排名优化、代理服务、手机自适应及搭建教程
  • (二) Windows 下 Sublime Text 3 安装离线插件 Anaconda
  • (附源码)spring boot网络空间安全实验教学示范中心网站 毕业设计 111454
  • (附源码)ssm高校升本考试管理系统 毕业设计 201631
  • (附源码)ssm基于web技术的医务志愿者管理系统 毕业设计 100910
  • (没学懂,待填坑)【动态规划】数位动态规划
  • (轉貼) UML中文FAQ (OO) (UML)
  • .NET CF命令行调试器MDbg入门(一)
  • .net core 6 redis操作类
  • .Net IOC框架入门之一 Unity
  • .NET 的静态构造函数是否线程安全?答案是肯定的!