【C++掌中宝】用最少的话让你全方位理解内联函数

在这里插入图片描述

文章目录

  • 引言
  • 1. 什么是内联函数
  • 2. 工作原理
  • 3. 内联函数的编程风格
  • 4. 使用限制
  • 5. 内联函数与宏的比较
  • 6. 优缺点
  • 7. 何时使用内联函数
  • 8. 补充
  • 9. 总结
  • 结语

引言

在C++编程中,函数的调用开销是程序运行效率的一个重要影响因素。为了解决频繁调用函数时的性能问题,C++提供了内联函数(inline),这是一种可以在编译阶段进行优化的技术。本文将详细介绍内联函数的概念、工作原理、使用限制以及与宏的比较。

1. 什么是内联函数

内联函数是使用inline关键字修饰的函数,目的是让编译器在函数调用时,将函数体直接展开到调用处,而不是通过常规的函数调用机制。其设计初衷是为了减少函数调用的开销,特别是在需要频繁调用的小型函数中。

例如,在以下代码中:

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

当调用add(3, 5)时,编译器会将该调用替换为3 + 5,从而避免了函数调用时的开销。

2. 工作原理

在程序执行过程中,常规函数的调用会涉及到参数传递、栈帧的建立与销毁,这一过程虽然对单次调用影响不大,但对于频繁调用的函数,这种开销将明显增加。内联函数通过在调用处直接展开函数体,消除了这些额外开销。

需要注意的是,内联仅仅是对编译器的建议,编译器可以根据实际情况决定是否展开内联函数。C++标准并没有规定编译器必须在何种情况下展开内联,因此不同编译器的处理可能有所不同。

例如:

#include <iostream>
inline char* checkOddEven(int a) {return (a % 2 > 0) ? "奇" : "偶";
}int main() {for (int i = 1; i < 100; i++) {std::cout << "i:" << i << " 奇偶性:" << checkOddEven(i) << std::endl;}
}

在上面的代码中,编译器将直接将checkOddEven(i)展开为(i % 2 > 0) ? "奇" : "偶",避免了每次循环调用函数的开销。

3. 内联函数的编程风格

  • inline必须与函数定义放在一起。仅仅在函数声明时加上inline关键字并不会使函数成为内联函数。
  • 内联函数一般应定义在头文件中,因为它们会在每个调用它的地方展开。
  • 不建议内联函数的声明和定义分离,可能会导致链接错误,因为inline被展开,就没有函数地址,链接时会出现报错。

错误示例:

inline void Foo(int x, int y);  // 声明不生效
void Foo(int x, int y) {// 函数体
}

正确示例:

inline void Foo(int x, int y) {// 函数体
}

4. 使用限制

  • 函数体必须足够简单:内联函数适用于小型、频繁调用的函数,过于复杂的函数不适合内联,因为代码膨胀会带来内存开销问题。
  • 递归函数不适合内联:内联函数不支持直接递归,即函数不能调用自身,因为这会导致无限展开,编译器将忽略内联请求。
  • 不适用于带有复杂控制结构的函数:如whileswitch等结构控制语句。

5. 内联函数与宏的比较

在C语言中,宏提供了类似的功能,但内联函数相比宏具有多项优势:

  • 类型检查:内联函数在编译时进行类型检查,而宏仅进行文本替换,可能导致难以发现的错误。
  • 调试友好:内联函数的调试信息更丰富,调试器能够识别函数的调用和执行路径,而宏则不易调试。
  • 作用范围:宏的文本替换可能会引发命名冲突和作用域污染,而内联函数则使用标准的函数调用机制。

示例:

#define SQUARE(x) ((x) * (x))
inline int square(int x) {return x * x;
}

相比宏,内联函数的调用方式更安全,也更加可控。

6. 优缺点

优点

  1. 提高运行速度:通过避免函数调用的开销,内联函数可以加速程序执行。
  2. 减少栈内存开销:不需要为每次函数调用建立栈帧。
  3. 更好的调试支持:内联函数在调试时更加直观。

缺点

  1. 代码膨胀:内联函数在调用处展开,会增加程序的代码体积,特别是在函数体较大时。
  2. 编译时间增加:内联函数可能增加编译时间,因为每次调用都需要展开函数体。
  3. 内联的局限性:并非所有函数都适合内联,编译器也可能选择不进行内联。

7. 何时使用内联函数

内联函数适用于小型、频繁调用且不涉及复杂逻辑的函数。以下场景适合使用内联函数:

  • 性能要求高:当函数的调用开销影响到程序性能时,内联可以帮助优化执行效率。
  • 替代宏定义:内联函数可以替代宏,避免宏带来的不安全性。

在类内部定义的函数默认是内联函数,适合隐藏类实现细节

8. 补充

vs编译器 debug版本下面默认是不展开inline的,这样方便调试,debug版本想展开需要设置一下以下两个地方。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

9. 总结

内联函数是C++中一种重要的优化手段,通过减少函数调用的开销来提高程序的运行效率。但它也有一定的局限性,特别是在代码膨胀和编译时间方面。因此,开发者在使用内联函数时应权衡利弊,合理选择合适的函数进行内联。总的来说,内联函数在优化小型、频繁调用函数时,能够带来显著的性能提升。

结语

这篇博客详细介绍了C++内联函数的概念、使用场景和优缺点,相信读者能够通过学习本文对内联函数有更深入的理解,并在实际开发中灵活运用内联技术来优化代码。

今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下。

也可以点点关注,避免以后找不到我哦!

Crossoads主页还有很多有趣的文章,欢迎小伙伴们前去点评,您的支持就是作者前进的动力!

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/150823.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

人工智能助力阿尔茨海默症治疗:微软与上海精神卫生中心的新研究

最近&#xff0c;微软研究院与上海市精神卫生中心合作&#xff0c;基于微软 Azure OpenAI 服务中的多模态大模型&#xff0c;开发了一种名为“忆我”&#xff08;ReMe&#xff09;的个性化认知训练框架。这一创新项目旨在通过数字化手段扩展自动化认知训练的范围&#xff0c;为…

如何瞬间建造一个百亿商品的网上商城?借助API,无需逐个上传商品数据,自动对接电商平台百亿商品数据

在快速发展的电商时代&#xff0c;构建一个拥有百亿级商品数据的网上商城曾是许多企业遥不可及的梦想。然而&#xff0c;随着技术的不断进步&#xff0c;特别是电商平台API接口的广泛应用&#xff0c;这一梦想正逐渐变为现实。本文将详细介绍如何通过调用电商平台API接口&#…

用AI绘画年入百万?揭秘高效起始号与现变路径...

part.1 AI绘画的优势 AI绘画的魅力在于其高效和灵活 无论你是通过Midjourney还是Stable Diffusion&#xff0c;只需输入简单的提示词&#xff0c;再加上一些额外的控制调整&#xff0c;AI绘画就能快速生成各种创意内容。角色IP设计、游戏原画、3D场景甚至是天马行空的创意都…

扫雷老年版2.0无猜模式

扫雷老年版2.0无猜模式 打破记录5秒&#xff0c;到达4秒。

Skywalking告警配置

背景 skywalking 9.7.0&#xff0c;地址&#xff1a;Backend setup | Apache SkyWalking helm&#xff1a;skywalking-helm:4.5.0&#xff0c;地址&#xff1a;skywalking-helm/chart/skywalking/values.yaml at v4.5.0 首先来说一下为什么使用skywalking告警&#xff1f; …

Java转换流

转换流 是字符流和字节流之间的桥梁 转换输出流:OutputSteamWriter 转换输入流:InputStreamReader InputStreamReader输入流 package myio;import java.io.*;public class inputsteamread {public static void main(String[] args) throws IOException {InputStreamReader…

基于SSM的家政服务网站【附源码】

基于SSM的家政服务网站&#xff08;源码L文说明文档&#xff09; 目录 4 系统设计 4.1 系统概述 4.2 系统结构 4.3. 数据库设计 4.3.1 数据库实体 4.3.2 数据库设计表 4.4 数据表 第5章 系统详细设计 5.1管理员功能模块 5.2用户功能模块 5.3前…

利用低代码快速搭建电商小程序之商品列表页

目标&#xff1a; 搭建商城的一个商品列表页面&#xff08;先做静态页&#xff09; 开发环境&#xff1a; 访问白码低代码平台&#xff1a;https://www.bnocode.com/ 白码的新自定义页功能&#xff08;使用vue框架&#xff09; 前期准备&#xff1a; 需要先准备商品数据表…

LeaferJS 动画、状态、过渡、游戏框架

LeaferJS 现阶段依然专注于绘图、交互和图形编辑场景。我们引入游戏场景&#xff0c;只是希望让 LeaferJS 被更多有需要的人看到&#xff0c;以充分发挥它的价值 LeaferJS 为你带来了全新的游戏、动画、状态和过渡功能&#xff0c;助你实现那些年少时的游戏梦想。我们引入了丰富…

读论文《OmniGen: Unified Image Generation》

OmniGen演示了在单一框架内执行各种图像生成任务的能力。此外&#xff0c;它还具有推理能力和语境学习能力。 论文地址&#xff1a;2409.11340v1 (arxiv.org) 项目地址&#xff1a;GitHub - VectorSpaceLab/OmniGen 项目目前还不完整&#xff0c;论文展现的通用性十分强大&am…

【云安全】云原生安全攻防

一、云原生安全 1、云原生介绍 云原生指构建和运行应用以充分利用通过云交付模式交付的分布式计算。云原生应用旨在充分利用云平台特有的可扩展性、弹性和灵活性优势。根据云原生计算基金会 (CNCF)的定义&#xff0c;云原生技术可帮助企业在公有云、私有云和混合云上构建和运行…

认知杂谈82《跳出信息茧房,持续精进》

内容摘要&#xff1a; 互联网时代&#xff0c;信息丰富&#xff0c;但便捷性削弱了我们的好奇心。互联网是双刃剑&#xff0c;快速获取知识的同时&#xff0c;也让我们陷入“信息茧房”&#xff0c;限制视野。 好奇心减少&#xff0c;部分原因是互联网的“懒惰效应”&#xff0…

ProcessOn为什么导出有水印!!!(利用SVG转PNG)

processon-svg2png ProcessOn 一个非常好用的思维导图网站&#xff0c;但是为什么导出有水印&#xff01;&#xff01;&#xff01;。 功能 支持按钮拖拽支持将流程图svg 转成 png下载支持修改自定义文字下载svg&#xff08;开发中&#xff09; 安装/使用方法 安装并使用…

亚马逊跨境电商测评补单系统防关联全攻略

在跨境电商领域&#xff0c;尤其是亚马逊、速卖通等平台上&#xff0c;测评补单已成为提升产品曝光度和销量的重要手段。然而&#xff0c;但多账号操作带来的关联风险始终是卖家们需要面对的一大问题。为了维护平台的公平秩序&#xff0c;这些各电商平台实施了严格的用户管理制…

Mysql梳理10——使用SQL99实现7中JOIN操作

10 使用SQL99实现7中JOIN操作 10.1 使用SQL99实现7中JOIN操作 本案例的数据库文件分享&#xff1a; 通过百度网盘分享的文件&#xff1a;atguigudb.sql 链接&#xff1a;https://pan.baidu.com/s/1iEAJIl0ne3Y07kHd8diMag?pwd2233 提取码&#xff1a;2233 # 正中图 SEL…

线性跟踪微分器TD详细测试(Simulink 算法框图+CODESYS ST+博途SCL完整源代码)

1、ADRC线性跟踪微分器 ADRC线性跟踪微分器(ST+SCL语言)_adrc算法在博途编程中scl语言-CSDN博客文章浏览阅读784次。本文介绍了ADRC线性跟踪微分器的算法和源代码,包括在SMART PLC和H5U平台上的实现。文章提供了ST和SCL语言的详细代码,并讨论了跟踪微分器在自动控制中的作用…

【C++掌中宝】C++ 中的空指针救世主——nullptr

文章目录 1. 什么是 NULL&#xff1f;2. NULL 在 C 和 C 中的区别3. C11 引入 nullptr 的原因4. nullptr 与 NULL 的区别5. nullptr 的应用场景6. 模拟 nullptr 的实现7. 总结结语 1. 什么是 NULL&#xff1f; 在 C 和 C 编程中&#xff0c;NULL 常用于表示空指针&#xff0c;…

《开题报告》基于SpringBoot的社区养老平台的设计与实现+学习文档+答辩讲解视频

开题报告 研究背景 随着社会的快速发展和人口老龄化趋势的加剧&#xff0c;养老服务已经成为一个日益重要的议题。传统的养老模式逐渐暴露出诸多不足&#xff0c;如服务内容单一、服务质量难以保证、管理效率低下等问题&#xff0c;无法满足老年人日益多样化、个性化的需求。…

导出Power bi中的Measure

工作中做交接文档时&#xff0c;有时需要导出Power BI中所有度量值&#xff0c;这时可以下载两个工具。 一 &#xff0c; 下载工具&#xff1a; 1 &#xff0c; DaxStudio&#xff1a; http://daxstudio.org/ 2&#xff0c; Vertipaq Analyzer&#xff1a; https://www.sqlbi.c…

编写程序将华氏温度78度转换为摄氏温度,转换成的摄氏温度要求输出。转换公式为:摄氏度=(5/9)*(华氏度-32)

目录 前言 一、代码部分 二、运行截图 前言 1.本文所讲的是java程序设计语言&#xff0c;其内容是在java语言程序设计实现摄氏温度的转换&#xff1b; 2.Java文件的编写以收入到我的专栏“Java”当中&#xff0c;其中有相关的系列文章&#xff1b; 3.本文的操作步骤具有…