C++学习笔记(5)——inline内联(改)

往期文章: C++学习笔记


理解与比喻

从功能上来看,内联是一种加强版的宏,赋予了宏更大的的自由性,其可编辑性与可读性得到了巨大的提升,让编译者在编译过程中可以更加细致地控制编译器的编译阶段。


打个比方,C语言的就像是个口哨,当指挥员想要快速下令时,他可以快速的下达几种简单的命令,且收令者可以快速理解并执行命令;

C++的内联更像是个扩音器,指挥员可以立即快速下达信息量更大的命令,收令者也可以立即理解并执行命令,但如果命令太长则失去了快速的特性,命令的性质也变成了口述计划。


一、什么是内联

用 inline修饰的函数称为内联函数,在C++编译器调用内联函数时,函数会直接在调用的地方展开。

内联函数存在的意义就是让程序员能使特定函数不要建立栈帧,从而提升程序运行速度。


二、使用内联

1.内联函数的使用决定权在编译器

a)内联函数的原理

编译期间编译器会用函数体替换函数调用

我们设立了两个函数,一个是普通函数my_Add,其中一个是内联函数func,func()在编译器编译过程中其代码被直接替换成它的函数体。
代码如下:

#include<iostream>
using namespace std;

int my_Add(int a,int b)
{
	int c = a + b;
	c = a - b;
	c = a / b;
	return c;
}

inline int func()
{
	int x1 = 0;
	int x2 = 0;
	int ret = 0;
	ret += x1;
	return ret;
}

int main()
{
	int d = my_Add(2, 3);
	int e = func();
	return 0;
}

可以看到,两个函数在编译过程中以不同的方式被调用。
在这里插入图片描述

b)内联函数被判定为普通函数

内联并非十全十美,如果编译器认为使用内联函数会导致代码膨胀,则编译器会私自把内联函数当作普通函数调用。
代码如下:

#include<iostream>
using namespace std;

inline int my_Add(int a,int b)
{
	int c = a + b;
	return c;
}

int main()
{
	int d = my_Add(2, 3);
	int e = my_Add(3, 3);
	return 0;
}

如图,这里编译器把内联函数判定为普通函数了。
在这里插入图片描述


三.内联函数的特性

a)inline内联函数——以空间换时间

编译器会在编译阶段会把内联函数的函数调用换成函数体,这样做的缺点是:可能发生代码膨胀,函数体过大且被反复调用,会使目标文件变大;优点是:减少了调用开销,提高了程序运行效率。

b)使用内联函数只是对编译器提议,编译器根据自身机制判断是否采用内联调用

建议将函数规模较小、不是递归且反复调用的函数设为inline内联函数,避免编译器自行否决编码者的意图。

c)inline内联——声明和定义不能分离

inline内联函数如果声明和定义分离则会导致链接错误。因为inline的原理是函数体替换函数调用,这种情况下inline内联函数没有建立栈帧也就没有函数地址,inline被展开后没有函数地址可供寻找,编译器无法拿着函数声明去找函数地址。


四.宏的优缺点

1、宏的优点:

  1. 代码复用性强。
  2. 性能强。

2、宏的缺点:

  1. 调试困难。
  2. 代码可读性插。
  3. 编译器无法检查宏的数据类型。

3、C++解决宏的问题

  1. 常量定义方面一律使用const enum,具体的变量类型根据程序员输入的内容由编译器自行判断。
  2. 短小函数一律用inline内联函数替换
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值