C++: 内联函数

news/2024/5/20 1:29:06 标签: C++, 内联函数

目录

概念:

与宏的对比:

函数膨胀:

内联函数的特性: 

概念:

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

举例:

inline int Add(int a, int b)
{
	return a + b;
}

int main()
{
	int ret1 = Add(1, 2) * 3;

	int x = 1, y = 2;
	int ret2 = Add(x | y, x & y);

	return 0;
}

内联函数的本质其实和C语言中的宏函数相差不多,但是对比于宏,内联函数仅仅只是代替和替换,并不会像宏函数一样在替换的同时建立栈帧。

换句话说,内联函数只是替换和展开,而非调用和建立栈帧!

与宏的对比:

而关于宏函数,虽然宏能够解决这种“需要频繁调用”、“且建立栈帧”的问题,但是宏的缺陷也十分的明显:

  • 语法复杂,坑很多
  • 不容易控制不能调试
  • 没有类型安全的检查 
#define ADD(a,b)((a)+(b)) //正确写法

#define ADD(a,b) a+b // 会有ret1 的情况发生  

#define ADD(a,b)(a+b) // 会有ret2的情况发生

//这个宏的本质其实是 将ADD(参数1 ,参数2 ) 替换成 参数1+参数2 
//但是直接替换所以要考虑的问题很多 


int main()
{
	int ret1 = Add(1, 2) * 3;

	int x = 1, y = 2;
	int ret2 = Add(x | y, x & y);

	return 0;
}

因为宏的本质上是替换,所以对于需要替换的内容十分的严谨,倘若一步错,则步步错,所以对于宏而言,内联函数其实是更加完善的,可以说内联函数其实是完善了宏的问题,解决了宏的缺点。 

函数膨胀:

实际上,内联函数使用的场景并不是很多,很多时候内联函数只是也只能使用在较为小型的函数当中,如果是较为大型或者调用函数的次数非常多时,内联函数就会导致函数膨胀问题的发生!

举例:如果inline定义了一个大概有着一百行的代码作为内联函数,而调用这个内联函数的代码有一万行,那么根据内联函数的替换原理,大概就会有一百万行的代码的运行量在这串代码当中。

所以,这也是为什么说内联函数实际上是空间换取时间的原因!

内联函数的特性:

1. inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会 用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运 行效率。

2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建 议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不 是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。 

3. inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址 了,链接就会找不到。

// F.h
#include <iostream>

using namespace std;

inline void f(int i);

// F.cpp
#include "F.h"

void f(int i)
{
 cout << i << endl;
}

// main.cpp
#include "F.h"

int main()
{
 f(10);
 return 0;
}


http://www.niftyadmin.cn/n/5350889.html

相关文章

从微服务到云原生

很多文章介绍云原生概念&#xff0c;说它包含微服务&#xff0c;又包含了其它几个方面的东西&#xff0c;还扯到文化层面、组织层面和技术层面&#xff0c;搞技术的人一听到公司文化问题和组织部门问题&#xff0c;就十分地晕眩&#xff0c;不能让我好好地坐下来写写代码、搞搞…

c#学习笔记-内存管理和gc优化

前言 在游戏运行的时候&#xff0c;数据主要存储在内存中&#xff0c;当游戏的数据在不需要的时候&#xff0c;存储当前数据的内存就可以被回收以再次使用。内存垃圾是指当前废弃数据所占用的内存。****GC即&#xff08;Gabarage Collector&#xff0c;垃圾回收器&#xff09;…

go语言将单反斜杠改为双反斜杠

最近开发的时候遇到这么个问题&#xff0c;就是在window上获取了文件目录的字段&#xff0c;然后将这个绝对路径保存到数据库&#xff0c;最后前端需要请求的时候&#xff0c;就需要读取数据库存的文件目录路径给前端&#xff0c;前端要进行展示。但是前端展示的时候路径的双反…

力扣0103——二叉树的锯齿形层序遍历

二叉树的锯齿形层序遍历 难度&#xff1a;中等 题目描述 给你二叉树的根节点 root &#xff0c;返回其节点值的 锯齿形层序遍历 。&#xff08;即先从左往右&#xff0c;再从右往左进行下一层遍历&#xff0c;以此类推&#xff0c;层与层之间交替进行&#xff09;。 示例1 …

如何在有或没有备份的 iPhone 上检索已删除的短信

iPhone 清理垃圾短信时不小心删除了一些重要短信&#xff1f;想知道如何找回 iPhone 上已删除的短信吗&#xff1f;如果您已将设备备份到 iCloud 或 iTunes&#xff0c;则可以从备份恢复 iPhone 上的短信。如果没有备份&#xff0c;您可以尝试第三方iPhone短信恢复程序来恢复它…

sql server 2008 安装问题

1、sql server 2008 安装程序支持文件后安装界面就消失&#xff1a; 打开cmd以管理员身份运行 复制或者手动输入以下命令&#xff1a;secedit /configure /cfg %windir%\inf\defltbase.inf /db defltbase.sdb /verbose运行完成后&#xff0c;重新安装 卸载需删除注册表这几个…

在 Vue 项目中,可以通过设置不同的环境变量来区分不同的环境,例如本地开发环境、测试环境和生产环境。以下是设置环境变量的步骤:

1、在src下新建三个文件夹 &#xff08;.env.local、.env.test 和 .env.prod&#xff09; 2、配置信息 .env.local VUE_APP_ENVlocal VUE_APP_API_URLhttp://localhost:8080.env.test VUE_APP_ENVtest VUE_APP_API_URLhttp://124.220.110.203:9090/ .env.prod VUE_APP_…

【C++基础】面向对象编程之重载、重写介绍

&#x1f308;欢迎来到C基础专栏 &#x1f64b;&#x1f3fe;‍♀️作者介绍&#xff1a;前PLA队员 目前是一名普通本科大三的软件工程专业学生 &#x1f30f;IP坐标&#xff1a;湖北武汉 &#x1f349; 目前技术栈&#xff1a;C/C、Linux系统编程、计算机网络、数据结构、Mysq…