【C++入门】你知道C++为什么会有内联函数吗?宏和内联函数的区别是什么?

在这里插入图片描述

👦个人主页:@Weraphael
✍🏻作者简介:目前学习C++和算法
✈️专栏:C++航路
🐋 希望大家多多支持,咱一起进步!😁
如果文章对你有帮助的话
欢迎 评论💬 点赞👍🏻 收藏 📂 加关注✨


前言

本章是补充C语言语法的不足,以及C++是如何对C语言设计不合理的地方进行优化的。

一、问题引入

我们每次去调用函数的时候,都会有消耗,例如建立栈帧等等。假设现在要调用100Add函数,那么就要建立100个栈帧。

在这里插入图片描述

在C语言中,为了防止如此大的消耗,我们通常用 宏函数 来解决问题。宏函数的优势是在预处理阶段就会被替换,不需要建立栈帧,提高了调用效率。

在这里插入图片描述

这里就得提提宏函数书写的经典错误了 (面试常考!!!)

  1. 宏函数本身不是函数,它是一种替换,因此不需要类型
  2. 末尾不需要分号
  3. 括号问题
    ① 有的人可能会这么写#define Add(x, y) x+y,那么如果有人给出这么一串代码Add(1, 1) * 2就会出现问题。原因是:宏替换后就会变成—>1 + 1 * 2,而我们期望的是先算1 + 1,然而宏替换后,根据运算符的优先级,它会先算1 * 2
    ② 还有的人可能会这么写#define Add(x, y) (x+y),那么如果有人给出这么一串代码Add(a|b, a&b) 就会出现问题。原因是:宏替换后就会变成–>(a|b + a&b),所以说,它还是因为优先级的问题,我们期望是先计算出a|ba&b,然而,根据运算符的优先级,它会先算b+a

宏既然有优点,那一定就会有缺点:复杂、不易调试、代码可读性差,还有特别容易写错。因此,C++祖师爷于是自创了一个新语法 — 内联函数

二、内联函数的概念

以关键字inline修饰的函数叫做内联函数在编译阶段,会在调用内联函数的地方展开没有函数调用建立栈帧的开销,能提升程序运行的效率。

所以,在【问题引入】中,用内联函数表示方法如下:

在这里插入图片描述

通过以上代码,我们可以看出内联函数的优点是(解决了宏的缺点):

  1. 不需要建立栈帧
  2. 不复杂、不容易出错、可读性好、容易调试

三、内联函数的特性

既然内联函数这么好,那可不可以将所有的函数都内联函数来表示?答案是当然不行,会导致代码膨胀(增加代码的体积)!内联函数只适用于短小其频繁调用的函数。

  1. inline是一种以空间换时间的做法。假如有一个Func函数在编译后有50行指令,假设要调用1wFunc函数,如果不使用内联函数,就会有1w+50行指令;但如果使用内联函数,在编译阶段,会用函数体替换函数调用,就会1w*50行指令,这会导致最后可执行程序(安装包)变大,可谁会希望一个程序的安装包大呢(安装时间长)?这就是代码膨胀,因此并不是所有的函数都能是内联函数。

  2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,最终是否会称为inline,编译器自己决定

我们可以测试以上Add函数是否是内联,在debug模式下,需要对编译器进行设置,否则不会展开。因为debug模式下,编译器默认不会对代码进行优化。

在这里插入图片描述

以下是调用函数的反汇编:

在这里插入图片描述

通过上图发现:并没有call Add(调用函数的汇编指令),说明函数体替换了函数调用。

那如果在内联函数内部多加几行代码,就可能不是内联函数了。例如:

在这里插入图片描述

  1. inline不建议声明和定义分离

在这里插入图片描述

看似没错,其实程序最后会报错

在这里插入图片描述

这是因为:分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到

在这里插入图片描述

所以 内联函数的定义和声明一定要在一起

在这里插入图片描述

四、宏的优缺点(面试题)

  • 优点:
  1. 增强代码的复用性。
  2. 提高性能
  • 缺点:
  1. 不方便调试宏。(因为预编译阶段进行了替换)
  2. 导致代码可读性差,可维护性差,容易误用。
  3. 没有类型安全的检查 。
  • C++有哪些技术替代宏?
  1. 常量定义换用constenum
  2. 短小函数定义换用内联函数
  • 9
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值