内联函数(inline)详解

article/2025/9/18 8:49:19

为什么要有内联函数

在学习内联函数之前,大家可以写一个实现加法的宏ADD(),检测一下自己。

如果对宏等预编译知识不太熟悉的话,可以先看一下这篇文章:预编译——2.2.4

以下是一个正确的ADD宏:

#define ADD(x,y) ((x)+(y))

灵魂三问:

  • 你在 x 和 y 前面加类型了吗?

  • x 和 y 都加括号了吗?

  • 整体加括号了吗?

如果以上三个问题都对了,那么恭喜你,宏定义表达式学的还不错

牛逼

一个简简单单的ADD(),就需要注意这么多问题,可以说宏这个知识点用起来着实是鸡肋,晦涩难懂;

同时宏也是不支持调试的,也没有类型安全的检查。

发明c++的大佬无疑也发现了这个问题,于是引出了内联函数的概念:用函数的语法解决的事。

可能兄弟们要说了,直接用函数不就好了?

如果是一个几十行的函数,函数本身执行就很耗时,那调用函数、创建栈帧的一两行可以忽略不计;但是如果一个函数本身就一两行,因为调用函数本身而产生的那一部分消耗,就格外突出,而宏或者内联的提前替换就显得格外优秀,提高了效率。

内联函数

语法

只需要在函数的最前面加一句 inline ,如下:

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

概念

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

inline int add(int a, int b)
{return a + b;
}
int main()
{int ret = 0, a = 1, b = 2;ret = a + b;ret = add(a, b);
}

为了观察内联函数的调用方式,我们看一下汇编代码:

image-20220513102655067

这是Debug模式下main函数的汇编代码。

可以发现 call add (0EA1465h)这一句其实是在调用函数,但是如果按照开始的定义,既然直接展开了,那就不会有调用函数这一步。

这是因为Debug模式下,为了调试方便,编译器默认不进行优化,也就是不会展开,依然使用一般函数的调用方式。

以下,在VS环境下,打开对 inline 的优化再展示一遍:

设置优化inline

image-20220513103607003

优化后的汇编代码:

(注:汇编代码的打开方式:F10或Fn+F10进到调试模式–>对任意语句右键–>转到反汇编)

image-20220513104111346

可以看到,优化之后inline修饰过的函数会直接展开。

也就是说,在Debug模式下你写代码、调试代码时,inline 相当于普通函数,可以进行调试;在release模式下,又可直接进行原地展开,提高效率(这里指的是避免了调用函数、创建栈帧等方面的资源消耗)

特性

  1. inline是一种以空间换时间的做法,省去调用函数、建立栈帧的额外开销;
    但是如果代码很长(一般是10行左右,具体取决于编译器),或者有递归函数,就不适宜使用递归函数。

  2. 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;
    }
    

    报错:

    error LNK2019: 无法解析的外部符号 “void __cdecl f(int)” (?f@@YAXH@Z),函数 _main 中引用了该符号

    分析:
    首先把.h中的内容替换到.cpp中,替换之后
    F.cpp

    #include <iostream>
    using namespace std;
    inline void f(int i);
    void f(int i)
    {cout << i << endl;
    }
    

    在编译过程中,编译器一看,这里的 f() 是个inline,

    inline就是说,“我”在调用的地方已经展开了,那么还需要这个给函数一个地址吗?不需要。

    也就说F.cpp生成的符号表中,不会有f()的地址。

    然后一链接,main.cpp中的 f(10); 就要去F文件给过来的符号表找 f() 的地址,找不到就会报链接错误。

    (注:如果大家对编译链接的知识感兴趣,可以看一下这篇文章:点我)

    改正:

    那怎么写呢?

    不在F.cpp中写这个函数的定义,直接把声明、定义(可以只有定义,更香)都放到 F.h 中去,预编译阶段会直接把内联函数换到main.cpp,相当于在main.cpp头顶上定义了这个内联函数,编译阶段就直接在调用的地方被展开。
    F.h

    #include <iostream>
    using namespace std;
    void f(int i)
    {cout << i << endl;
    }
    

    main.cpp

    #include "F.h"
    int main()
    {f(10);return 0;
    }
    

知识大总结

  • 宏的优缺点:
    • 优点:
      1. 增强代码的复用性。
      2. 提高性能。
    • 缺点:
      1. 不方便宏调试(因为预编译就进行了替换)
      2. 导致代码可读性变差,可维护性变差,容易误用。
      3. 没有类型安全的检查。
  • C++有哪些技术替代宏:
    1. 常量定义——换用const
    2. 函数定义——换用内联函数


- 优点:
1. 增强代码的复用性。
2. 提高性能。
- 缺点:
1. 不方便宏调试(因为预编译就进行了替换)
2. 导致代码可读性变差,可维护性变差,容易误用。
3. 没有类型安全的检查。

  • C++有哪些技术替代宏:
    1. 常量定义——换用const
    2. 函数定义——换用内联函数

http://chatgpt.dhexx.cn/article/gJ3Wb1xO.shtml

相关文章

内联函数(超详细版)

1.内联函数的由来 当我们调用函数的时候&#xff0c;实际会有额外的开销&#xff0c;为了避免或减少这些额外的开销&#xff0c;c中引入内联函数&#xff08;inline functions&#xff09;。 2.内联函数的原理 1&#xff09;当我们调用内联函数时&#xff0c;不会像调用普通函…

如何证明一个问题是NP-Hard或NP-Complete?

文章目录 NP-hard vs NP-CompleteReduction SAT ProblemReducing SAT to Shortest Clique ProblemReducing SAT to Shortest Tour Problem A List of NP-CompleteSet Vertex Cover Problem & Independent SetK-coloring and CliquePackingLongest Common Subsequence 参考资…

【机器学习】P问题、NP问题、NP-hard、NP-C问题解析与举例理解

目录 1 基本概念1.1 多项式和时间复杂度1.2 P和NP1.3 NP-hard和NP-C1.4 总结 2 举例理解NP问题3 其他NP问题 1 基本概念 1.1 多项式和时间复杂度 &#xff08;1&#xff09;多项式 a x n b x n − 1 c ax^nbx^{n-1}c axnbxn−1c&#xff0c;形如这种形式的就被称为x的最高…

P问题、NP问题、NPC问题、NP-hard问题详解

要理解P问题、NP问题、NPC问题、NP-hard问题&#xff0c;需要先弄懂几个概念&#xff1a; 什么是多项式时间&#xff1f;什么是确定性算法&#xff1f;什么是非确定性算法&#xff1f;什么是规约/约化&#xff1f; 文章目录 多项式时间&#xff08;Polynomial time&#xff09…

什么是P=NP问题?

来自&#xff1a;后端技术指南针 1 前言 今天和大家一起了解个高能知识点&#xff1a;PNP问题。 看到这里我们可能是一头雾水&#xff0c;不由得发问&#xff1a; P问题是什么&#xff1f;NP问题又是什么&#xff1f;PNP又是什么意思&#xff1f;研究并解决PNP问题的意义是什么…

NP问题总结(概念+例子+证明)

目录 基本概念 证明思路 常见例子 21个常见NPC问题 原理论证 基本概念 P类问题:(polynominal) 存在多项式时间算法的问题&#xff0c;即在多项式时间内可解的问题&#xff1b; 例如&#xff1a;冒泡排序、快速排序等问题&#xff1b; NP类问题:(Nondeterministic pol…

[知识归纳]关于NP问题的概念与解释 | NP-complete NP-hard

NP问题 P问题是一类可以通过确定性图灵机在多项式时间(Polynomial time)内解决的问题集合。NP问题是一类可以通过非确定性图灵机( Non-deterministic Turing Machine)在多项式时间(Polynomial time)内解决的决策问题集合。 多项式时间&#xff08;Polynomial time&#xff09…

P问题、NP问题、NP完全问题和NP-hard问题

在讲P类问题之前先介绍两个个概念&#xff1a;多项式&#xff0c;时间复杂度。(知道这两概念的可以自动跳过这部分) 1、多项式&#xff1a; 恩....就是长这个样子的&#xff0c;叫x最高次为n的多项式.... 2、时间复杂度 在计算机算法求解问题当中&#xff0c;经常用时间复…

P问题、NP问题、NPC问题、NPH问题详解

P&#xff1a; Polynomial&#xff0c;是指能在多项式时间内解决的问题&#xff1b;&#xff08;如果一个问题可以找到一个能在多项式的时间里解决它的算法&#xff0c;那么这个问题就属于P问题。P是英文单词多项式的第一个字母。&#xff09;NP&#xff1a;Non-deterministic …

判断凸多边形(向量叉积运用)

469. 凸多边形 - 力扣&#xff08;LeetCode&#xff09; 给定 X-Y 平面上的一组点 points &#xff0c;其中 points[i] [xi, yi] 。这些点按顺序连成一个多边形。 如果该多边形为 凸 多边形&#xff08;凸多边形的定义&#xff09;则返回 true &#xff0c;否则返回 false 。…

【编程题】判断一个多边形是否为凸多边形

题目&#xff1a; 顺序输入点的坐标&#xff0c;判断按这些点顺序连接起来的多边形是否为凸多边形还是凹多边形 输入描述&#xff1a; 输入包括两行&#xff1b; 第一行是一个整数n&#xff0c;n>3&#xff0c;作为提示输入的顶点数量 第二行为2*n个整数&#xff0c;为各点…

10343 划分凸多边形(优先做)

题目描述 10343 划分凸多边形&#xff08;优先做&#xff09; 时间限制:800MS 代码长度限制:10KB 提交次数:0 通过次数:0 题型: 编程题 语言: G;GCC;VC;JAVA Description 问题描述&#xff1a;一个正凸N边形&#xff0c;可以用N-3条互不相交的对角线将正N边形分成N-2个三角形…

N顶点凸多边形中对角线交点的个数

题目描述 对于一个N个定点的凸多边形&#xff0c;他的任何三条对角线都不会交于一点。请求楚图形中对角线交点的个数。 例如&#xff0c;6边形&#xff1a; 我们可以发现&#xff0c;两条不平行对角线才会有一个交点&#xff0c;同时&#xff0c;两条对角线又确定了一个四边形…

凸多边形的划分

题目&#xff1a; 给定一个具有 NN 个顶点的凸多边形&#xff0c;将顶点从 11 至 NN 标号&#xff0c;每个顶点的权值都是一个正整数。 将这个凸多边形划分成 N−2N−2 个互不相交的三角形&#xff0c;对于每个三角形&#xff0c;其三个顶点的权值相乘都可得到一个权值乘积&a…

`算法知识` 多边形, 凸多边形, 外接矩形

catalog 图片引用图二 多边形分类周长多边形的外接矩形 凸多边形去除若干点, 仍为凸多边形 ID_COUNT: 3 图片引用 图二 多边形 以下讨论, 均在(笛卡尔坐标系)中, 即两点间的距离为 (欧几里得距离) 由N条边和N个点组成, N > 3, 面积一定> 0 每条边, 都是(线段) 线段: 必…

判断多边形的凹凸性和计算多边形面积:利用向量叉乘

根据百度百科的讲解&#xff1a; 凸多边形 现在重点讲解顶点凹凸性法&#xff08;最常用也是较为简单的方法&#xff09;&#xff1a;计算总结在最后。 利用向量叉乘的相关知识进行计算&#xff1a;假设当前连续的三个顶点分别是P1&#xff0c;P2&#xff0c;P3。计算向量P1P3…

判断点在凸多边形內

判断点在凸多边形內 判断点在凸多边形内的算法有很多&#xff0c;可以参考链接3&#xff0c;个人尝试使用了同侧法&#xff0c;此处也只解析这个方法 算法原理&#xff1a; 同侧法是判断点在向量哪一侧的一个方法&#xff0c;这个算法的概念是来自于参考文献一&#xff0c;参…

—【动态规划】凸多边形最优三角剖分

0014算法笔记——【动态规划】凸多边形最优三角剖分 分类&#xff1a; 算法 2013-03-05 20:10 612人阅读 评论(0) 收藏 举报 三角剖分 凸多边形最优解 动态规划 算法笔记 1、问题相关定义&#xff1a; (1)凸多边形的三角剖分&#xff1a;将凸多边形分割成互不相交的三角形的…

0014算法笔记——【动态规划】凸多边形最优三角剖分

1、问题相关定义&#xff1a; (1)凸多边形的三角剖分&#xff1a;将凸多边形分割成互不相交的三角形的弦的集合T。 (2)最优剖分&#xff1a;给定凸多边形P&#xff0c;以及定义在由多边形的边和弦组成的三角形上的权函数w。要求确定该凸多边形的三角剖分&#xff0c;使得该三角…

判断平面多边形的凹凸性

对于平面多边形的三角化处理也是计算机图形学里面的一个领域&#xff0c;最近由于项目的需要&#xff0c;需要对平面多边形进行剖分&#xff0c;特此对其作了些研究。 在对平面多边形进行处理的时候&#xff0c;很多时候需要知道多边形的凹凸性&#xff0c;本文介绍两种方法来…