您现在的位置是:首页 >技术杂谈 >C++ 学习 ::【基础篇:06】:C++ (inline)内联函数的介绍及其出现的意义【对比于 C语言宏函数】网站首页技术杂谈

C++ 学习 ::【基础篇:06】:C++ (inline)内联函数的介绍及其出现的意义【对比于 C语言宏函数】

MortalSoul&Code 2024-06-29 06:01:02
简介C++ 学习 ::【基础篇:06】:C++ (inline)内联函数的介绍及其出现的意义【对比于 C语言宏函数】

本系列 C++ 相关文章 仅为笔者学习笔记记录,用自己的理解记录学习!C++ 学习系列将分为三个阶段:基础篇、STL 篇、高阶数据结构与算法篇,相关重点内容如下:

  1. 基础篇类与对象(涉及C++的三大特性等);
  2. STL 篇学习使用 C++ 提供的 STL 相关库
  3. 高阶数据结构与算法篇手动实现自己的 STL 库设计实现高阶数据结构,如 B树、B+树、红黑树等。

学习集:


本期内容:C++ (inline)内联函数的介绍及其出现的意义【对比于 C语言宏函数】


目录:
1. inline 内联函数的概念及使用方式
2. 关于函数栈帧的简单说明
3. 内联函数出现的意义:减少栈帧的开销提升程序运行效率
- - 3.1 高耗栈帧情形(内联函数适用情形)
- - 3.2 C 语言的解决方案:宏函数
- - 3.3 C++ 的解决方案:内联函数
4. 内联函数的注意点


C++学习合集链接


1. inline 内联函数的概念及使用方式

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

内联函数的使用方式:inline 类型 函数名(){}

/* C++ 方式定义一个内联函数:实现 add 加和。 */
inline int Add(int a, int b){
    return a+b;
}

2. 关于函数栈帧的简单说明

简而言之,函数在被调用时,编译器是会给被调用函数在栈区分配一个空间的!即:该过程使用空间申请的!

在这里插入图片描述


3. 内联函数出现的意义:减少栈帧的开销提升程序运行效率


3.1 高耗栈帧情形(内联函数适用情形)

若程序中出现较为电销的函数(1-10行),同时又频繁调用(如:10万次)。

如:在排序算法中使用的 swap 函数,对大量数据进行排序时,交换次数水涨船高!

  • C语言的解决方式:使用宏函数!
  • C++ 的解决方式:内联函数!

3.2 C 语言的解决方案:宏函数

宏的优缺点:

  • 缺点:
  1. 可读性差;
  2. 没有类型安全检查、不方便调试(直接替换如代码中)

  • 优点:代码可维护性高(一改全改)、宏函数提高效率(减少栈帧建立)
/* C 语言方式定义一个宏函数:实现 add 加和。 */
#define ADD(a+b) {(a)+(b)}		/* 写法错误 */
#define ADD(a,b) {(a)+(b)}		/* 写法错误 */
#define ADD(a,b) a+b			/* 写法错误 */
#define ADD(a,b) {return a + b;}			/* 写法错误 */
#define ADD(int a, int b) {return a + b;}	/* 写法错误 */

#define ADD(a,b) ((a)+(b))

int main(){
    // 一般而言,写出的宏函数能解决以下形式的适配问题基本就对
    ADD(1, 2);			
    
    if(ADD(1, 2)){}
    
    ADD(1, 2)*3;
    
    int x = 1, y = 2;
    ADD(x | y, x & y);
    
    return 0;
}

3.3 C++ 的解决方案:内联函数

  • 内联函数会在被调用处直接展开,好比在被调用处直接写了对应的函数功能(实现内联函数相当于就是提供代码复用性)
  • 内联函数几乎解决了宏(函数)的缺点!
  • C++ 中基本不再建议使用宏!
#include<iostream>
using namespace std;

int sum(int a, int b) {
	return a + b;
}

inline double sum(double a, double b) {
	return a + b;
}

int main() {

	sum(1, 1);

	sum(1.2, 2.2);	/* 调用内联函数相当于在此处直接实现两个 double 值的运算 */

	return 0;
}

4. 内联函数的注意点

  1. inline 是一种 以空间换时间 的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。
  2. inline 对于编译器而言只是一个建议,不同编译器关于 inline 实现机制可能不同,一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用 inline 修饰,否则编译器会忽略inline特性。
  3. inline不建议声明和定义分离,分离会导致链接错误。因为 inline 被展开,就没有函数地址了,链接就会找不到。

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。