C++函数内联详解

本文旨在讲解C++中的函数内联相关知识,读完这篇文章,希望读者们会对函数内联有更深一步的认识!


内联函数的定义

在计算机科学中, 内联函数 (有时称作 在线函数 或 编译时期展开函数 )是一种编程语言结构,用来建议 编译器 对一些特殊 函数 进行内联扩展(有时称作在线扩展 ;也就是说建议编译器将指定的函数体插入并取代每一处调用该函数的地方( 上下文 ),从而节省了每次调用函数带来的额外时间开支)


C++引进内联函数的原因

C++语言支持内联函数,其目的是为了提高函数的执行效率(速度)。


宏定义的缺陷

在C程序中,常常使用宏定义来提高代码执行效率宏定义本身不是一种函数,它只是一种简单的替代,其省去了参数压栈,生成汇编语言的CALL调用,返回参数,执行return等过程,从而提高了速度使用宏定义的最大缺点是容易出错,预处理器在拷贝宏代码时常常会产生意想不到的边界效应!通过阅读下面代码可以发现宏定义的一些缺点!

1.代码容易出错

#define Add(x,y)  x+y
int main()
{int result = 3 * Add(1, 2);cout << result << endl;        //结果输入5!
}

对于上述代码,初学者很容易将宏函数代码写错,没有加上括号,从而导致结果与自己预期的结果有出入!

2.宏定义不可调试

宏的另一个缺点就是不可调试,但是内联函数可以调试,内联函数不是像宏一样进行代码的展开么?怎么能够调试呢?其实内联函数的“可调试”不是说它展开后还可以调试,而是在程序的调试版本(Debug)版本里它根本没有真正的内联,编译器像普通函数那样为它生成含有调试信息的可执行代码,在程序的发行(Release)版本里,编译器才会实现真正的内联,所以我们可以通过release版本来观察其内联的实现过程!

判断函数成为内联函数

可以通过简单的调试,将代码转化为汇编代码,然后通过观察底层的实现,因为调用函数栈帧会使用Call指令,这是一种简单的观察方法!


内联函数的编程风格

注:内联函数的定义和声明不能分离!

关键字Inline必须与函数定义体放在一起才能使函数实现真正的内联,仅把inline放在函数声明的前面不起任何作用!

例如如下代码!

如下风格的Add函数不能成为内联函数!
inline void Add(int x,int y); //inline仅与函数放在声明放在一起
void Add(int x,int y)
{********
}如下风格的Add函数可以成为内联函数!void Add(int x,int y);
inline void Add(int x,int y) //inline与函数定义体放在一起!
{********
}

上述不能成为内联函数的情况编译器会报出如下错误!错误如下:

编译器不能链接Add函数,这是为什么呢?因为定义时把Add函数定义为内联类型,其作用只是单纯的展开函数,其不会在符号表调用相关字符,地址等,所以当引用Add函数时,虽然编译器认识这个函数,但是它不知道下一步该干什么(如何链接到Add函数)!

所以说,inline是一种“用于实现的关键字”,而不是一种“用于声明的关键字”,一般情况下,用户可以阅读函数声明的声明,但看不见函数的定义,尽管大多数教科书中在内联函数的声明和定义都加上了inline关键字,但是根据C++程序设计风格,inline不应出现在函数的声明中,因为用户没有必要知道函数是否需要内联!


内联函数的特性

1. inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率。

2. inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。


慎用内联函数

内联能提高函数的执行效率,为什么不把所有的函数都定义为内联函数呢?

如果所有的函数都是内联函数,还用得着“内联”这个关键字么?

内联并不是万能的!它以空间换时间为代价,仅仅省去了函数调用的开销,从而提高了程序的执行效率,注意:这里的“函数的调用开销”并不包括执行函数体所需要的开销,而是仅指参数压栈,跳转,退栈和返回操作,如果执行函数体内的代码时间比调用函数开销要大的多,那么内联的效率收入会很小,另一方面,每一处内联函数的调用都需要拷贝代码,使得程序的总代码量增大,消耗更多的内存空间!

以下情况不宜使用内联:

1.函数体内的代码较长,使用内联会使执行代码膨胀!

2.函数体内存在过多的循环或控制结构,那么执行函数体内的代码的时间会比函数调用开销大的多,因此内联的意义并不大!


至此,有关内联函数的介绍完毕,一些专业术语查自(高质量程序设计指南C/C++),希望读完这篇文章,能使读者对内联函数有更深一步的认识!

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

详解Vue中的render: h => h(App)

声明:只是记录&#xff0c;会有错误&#xff0c;谨慎阅读 我们用脚手架初始化工程的时候&#xff0c;main.js的代码如下 import Vue from vue import App from ./App.vueVue.config.productionTip falsenew Vue({// 把app组件放入容器中render: h > h(App), }).$mount(#ap…

洛谷P8814:解密 ← CSP-J 2022 复赛第2题

【题目来源】https://www.luogu.com.cn/problem/P8814https://www.acwing.com/problem/content/4732/【题目描述】 给定一个正整数 k&#xff0c;有 k 次询问&#xff0c;每次给定三个正整数 ni&#xff0c;ei&#xff0c;di&#xff0c;求两个正整数 pi&#xff0c;qi&#xf…

vue中的几种name属性

vue中的几种name属性 组件名name name选项 export default{name:xxx } // 获取组件的name属性 this.$options.namevue-devtools调试工具里显示的组件名称&#xff1b; 未配置name选项&#xff0c;就是组件的文件名&#xff1b; vue3配置name通过defineOptions()函数 de…

flink cdc多种数据源安装、配置与验证

搜索 flink cdc多种数据源安装、配置与验证 文章目录 1. 前言2. 数据源安装与配置2.1 MySQL2.1.1 安装2.1.2 CDC 配置2.2 Postgresql2.2.1 安装2.2.2 CDC 配置2.3 Oracle2.3.1 安装2.3.2 CDC 配置2.4 SQLServer2.4.1 安装2.4.2 CDC 配置3. 验证3.1 Flink版本与CDC版本的对应关系…

nlp系列(7)实体识别(Bert)pytorch

模型介绍 本项目是使用Bert模型来进行文本的实体识别。 Bert模型介绍可以查看这篇文章&#xff1a;nlp系列&#xff08;2&#xff09;文本分类&#xff08;Bert&#xff09;pytorch_bert文本分类_牧子川的博客-CSDN博客 模型结构 Bert模型的模型结构&#xff1a; 数据介绍 …

MySQL——常见问题

NULL和空值的区别 1、空值不占空间&#xff0c;NULL值占空间。当字段不为NULL时&#xff0c;也可以插入空值。 2、当使用 IS NOT NULL 或者 IS NULL 时&#xff0c;只能查出字段中没有不为NULL的或者为 NULL 的&#xff0c;不能查出空值。 3、判断NULL 用IS NULL 或者 is no…

46、TCP的“三次握手”

在上一节中&#xff0c;TCP首部常用的几个选项&#xff0c;有些选项的参数就是在通信双方在建立TCP连接的时候进行确定和协商的。所以在学习过TCP报文首部之后&#xff0c;下面我们开始学习TCP的连接建立。 TCP的一个特点是提供可靠的传输机制&#xff0c;还有一个特点就是TCP…

排序(408)

一、插入排序&#xff08;直接、折半、希尔&#xff09; 【2009统考】若数据元素序列{11,12,13,7,8,9,23,4,5}是采用下列排序方法之一得到的第二趟排序后的结果&#xff0c;则该排序算法只能是&#xff08;B&#xff09; A、冒泡排序 B、插入排序 C、选择排序 …

Elasticsearch 分布式搜索——聚合

1.聚合的种类 聚合常见的有三类&#xff1a; **桶&#xff08;Bucket&#xff09;**聚合&#xff1a;用来对文档做分组 TermAggregation&#xff1a;按照文档字段值分组&#xff0c;例如按照品牌值分组、按照国家分组Date Histogram&#xff1a;按照日期阶梯分组&#xff0c;例…

【C++】反向迭代器精讲(以list为例)

目录 二&#xff0c;全部代码 三&#xff0c;设计思路 1. 讨论 2. 关于迭代器文档一个小细节 结语 一&#xff0c;前言 如果有小伙伴还未学习普通迭代器&#xff0c;请参考这篇文章中的普通迭代器实现。 【STL】list用法&试做_底层实现_花果山~~程序猿的博客-CSDN…

Kotlin 环境下解决属性初始化问题

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…

npm install依赖冲突解决办法

今天npm的时候发现报错&#xff0c;原来是依赖冲突了 npm后面加上这个指令就可以顺利的安装依赖了。问题主因就是不同开发用了不同版本node导致依赖版本不同&#xff0c;出现了成功冲突&#xff0c;这是段指令&#xff1b;它告诉npm忽略项目中引入的各个依赖模块之间依赖相同但…

【Linux系列】vmware虚拟机网络配置详解

非原创 原文地址[1] 首发博客地址[2] 系列文章地址[3] vmware 为我们提供了三种网络工作模式&#xff0c;它们分别是&#xff1a;Bridged&#xff08;桥接模式&#xff09;、NAT&#xff08;网络地址转换模式&#xff09;、Host-Only&#xff08;仅主机模式&#xff09;。 打开…

TCP原理(全网最详细)

一、确认应答&#xff08;可靠性机制&#xff09; TCP诞生的初衷就是可靠传输 可靠传输是TCP最核心的部分&#xff0c;TCP内部很多机制都是在保证可靠传输&#xff08;可以理解为发一条消息&#xff0c;上面显示已读未读&#xff0c;可靠传输就是发一条消息我知道对方是否收到…

前端实现展开收起的效果 (react)

需求背景&#xff1a;需要实现文本的展开收起效果&#xff0c;文本是一行一行的&#xff0c;数据格式是数组结构。 如图所示&#xff08;图片已脱敏&#xff09; 简单实现&#xff1a;使用一个变量控制展开收起效果。 展开收起逻辑部分&#xff08;react&#xff09; const […

C++——特殊类设计

C——特殊类设计 文章目录 C——特殊类设计特殊类设计一个类不能被拷贝设计一个类只能在堆上创建设计一个类只能在栈上创建设计一个类不能被继承 单例模式饿汉模式懒汉模式 特殊类 设计一个类不能被拷贝 拷贝只会放在两个场景&#xff0c;其一是拷贝构造函数&#xff0c;其二是…

Rocky(Centos)安装中文字体(防止中文乱码)

1、查看字体列表 运行下列命令 fc-list 若出现&#xff0c;下面截图&#xff0c;则需要安装字体管理软件 安装字体库&#xff0c;运行&#xff1a; yum -y install fontconfig 当看到下图的提示信息时说明已安装成功&#xff1a; 二、添加中文字体 1&#xff09;window…

python实现adb辅助点击屏幕工具

#!/usr/bin/env python # -*- coding: utf-8 -*-import re import os import time import subprocess import tkinter as tk from tkinter import messagebox from PIL import Image, ImageTk# 设置ADB路径&#xff08;根据你的系统和安装路径进行调整&#xff09; ADB_PATH C…

centos+jenkins+pycharm

思路&#xff1a;架构 一. 在centos上搭建jenkins环境 二. pycharm与gitee建立连接 三. 访问jenkins&#xff0c;添加任务 3.1 添加一个自由风格的任务 3.2 添加git项目路径及访问git的账号和密码 3.3 执行start.sh脚本 四. 浏览器访问jenkins执行任务

MySQL--MySQL表的增删改查(基础)

排序&#xff1a;ORDER BY 语法&#xff1a; – ASC 为升序&#xff08;从小到大&#xff09; – DESC 为降序&#xff08;从大到小&#xff09; – 默认为 ASC SELECT … FROM table_name [WHERE …] ORDER BY column [ASC|DESC], […]; *** update