C++浅析内联函数的使用

 更新时间:2022年05月16日 15:14:37   作者:Hiland.  
为了消除函数调用的时空开销,C++ 提供一种提高效率的方法,即在编译时将函数调用处用函数体替换,类似于C语言中的宏展开。这种在函数调用处直接嵌入函数体的函数称为内联函数(Inline Function),又称内嵌函数或者内置函数

一. 概念

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

在C++里为了提高效率使用内联函数,可是我们会发现在C语言里面已经有了宏,也可以处理关于这个效率的问题,那为什么还会出现内联函数呢?

当我们要写一个Add的宏时:

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

但是也有人可能会写错,出现下面这些情况,比如:

#define Add(x, y) return x + y ; 
#define Add(x, y) return (x + y);
#define Add(x, y) return (x + y)
#define Add(x, y) x + y
#define Add(x, y) x + y;
#define Add(x, y) (x + y);
#define Add(x, y) (x + y)

以上这些都是有可能会出现的情况,既然这么容易写错,于是乎C++就出现了内联函数,就是为了解决宏函数晦涩难懂,容易写错的问题

那么如何查看内联函数呢?

我们知道宏是不支持调试的,但是内联函数是支持调试的,那内联函数怎么支持调试的呢?其实内联函数在debug版本下是不会展开的,如图:

但是release版本下又看不到汇编代码,为了能查看内联函数,我们需要更改一些设置提高优化等级,在debug模式下,需要对编译器进行设置,否则不会展开,因为debug模式下,编译器默认不会对代码进行优化,以下给出vs2019的设置方式,如下图:(这里由于疏忽忘记在函数前加上inline,记得加上并重新编译以后在调试状态下转到反汇编查看)

这些配置好了以后再次查看汇编代码:

我们就会发现这里不再call函数了,说明没有建立函数栈帧,而是直接展开了,inline起作用了这里

二. 特性

  • inline是一种以空间换时间的做法,省去调用函数额开销(建立栈帧)。所以代码很长或者有循环/递归的函数不适宜使用作为内联函数。(一般十行左右的代码使用)
  • inline对于编译器而言只是一个建议,编译器会自动优化,如果定义为inline的函数体内有循环/递归或者代码太长等等,编译器优化时会忽略掉内联。
  • inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。

声明和定义分离以后会报链接错误:

回顾:

宏的优缺点?

优点:

1.增强代码的复用性。

2.提高性能。

缺点:

1.不方便调试宏。(因为预编译阶段进行了替换)

2.导致代码可读性差,可维护性差,容易误用。

3.没有类型安全的检查 。

扩展:

C++有哪些技术替代宏?

1. 常量定义 换用const

2. 函数定义 换用内联函数

到此这篇关于C++浅析内联函数的使用的文章就介绍到这了,更多相关C++内联函数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C++广播通信实例

    C++广播通信实例

    这篇文章主要介绍了C++实现广播通信的方法,实例讲述了C++ socket广播通信的原理与实现方法,需要的朋友可以参考下
    2014-10-10
  • C++实现单链表删除倒数第k个节点的方法

    C++实现单链表删除倒数第k个节点的方法

    这篇文章主要介绍了C++实现单链表删除倒数第k个节点的方法,结合实例形式分析了C++单链表的定义、遍历及删除相关操作技巧,需要的朋友可以参考下
    2017-05-05
  • Java C++ leetcode面试零矩阵

    Java C++ leetcode面试零矩阵

    这篇文章主要为大家介绍了Java C++题解leetcode面试零矩阵示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-10-10
  • C++ Boost PointerContainer智能指针详解

    C++ Boost PointerContainer智能指针详解

    智能指针是一种像指针的C++对象,但它能够在对象不使用的时候自己销毁掉。虽然STL提供了auto_ptr,但是由于不能同容器一起使用(不支持拷贝和赋值操作),因此很少有人使用。它是Boost各组件中,应用最为广泛的一个
    2022-11-11
  • C/C++预处理浅析使用形式

    C/C++预处理浅析使用形式

    预处理是指在进行编译的词法扫描和语法分析之前所作的工作。预处理指令指示在程序正式编译前就由编译器进行的操作,可放在程序中任何位置。处理完毕自动进入对源程序的编译。C/C++中的预处理主要包含三种:文件包含、宏定义、条件编译
    2022-09-09
  • C++变换迭代器使用方法小结

    C++变换迭代器使用方法小结

    本文主要介绍了C++变换迭代器使用方法小结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2025-04-04
  • 聊聊C++的mutable和volatile

    聊聊C++的mutable和volatile

    这篇文章主要介绍了C++的mutable和volatile的相关资料,帮助大家更好的理解和学习c++,感兴趣的朋友可以了解下
    2020-09-09
  • 如何使用C语言实现平衡二叉树数据结构算法

    如何使用C语言实现平衡二叉树数据结构算法

    对于判断是否为平衡二叉树而言,我们需要知道以下特性:是一个二叉树也是一个二叉排序树该树的每个结点上的(深度)左子树 - 右子树的值为平衡因子(BF(Balance Factor))该树的每一个节点的左子树和右子树的高度至多等于1(平衡因子只可能是-1,0,1)
    2021-08-08
  • C/C++解析文件名和目录路径的方法

    C/C++解析文件名和目录路径的方法

    #include <libgen.h> 是一个 C/C++ 语言的头文件,主要用于字符串处理,特别是在处理文件路径时,它提供了一些函数来帮助你解析文件名和目录路径,本文就给大家介绍一下C/C++解析文件名和目录路径的方法,需要的朋友可以参考下
    2024-10-10
  • C语言sizeof和strlen的指针和数组面试题详解

    C语言sizeof和strlen的指针和数组面试题详解

    strlen是函数,字符串长度,不包括停止符。而sizeof则是内存块的大小,包括停止符。数组是一种数据类型,数据类型的本质就是固定大小,内存块的别名。可以用sizeof()一般都是数据类型
    2022-04-04

最新评论