C++ 内联函数inline

        内联函数是C++为提高程序运行速度所做的一项改进。常规函数和内联函数之间的主要区别不在于编写方式,面在于C+编译器如何将它们组合到程序中。要了解内联函数与常规函数之间的区别,必须深入到程序内部。

        编译过程的最终产品是可执行程序一一由一组机器语言指令组成。运行程序时,操作系统将这些指令载入到计算机内存中,因此每条指令都有特定的内存地址。计算机随后将逐步执行这些指令。有时 (如有循环或分支语句时),将跳过-些指令,向前或向后跳到特定地址。

        常规函数调用也使程序跳到另一个地址(函数的地址),并在函数结束时返回。下面更详细地介绍这一过程的典型实现。执行到函数调用指令时,程序将在函数调用后立即存储该指令的内存地址,并将函数参数复制到堆栈(为此保留的内存块),跳到标记函数起点的内存单元,执行函数代码(也许还需将返回值放入到寄存器中),然后跳回到地址被保存的指令处(这与阅读文章时停下来看脚注,并在阅读完脚注后返回到以前阅读的地方类似),来回跳跃并记录跳跃位置意味着以前使用函数时,需要一定的开销。

        C++内联函数提供了另一种选择。内联函数的编译代码与其他程序代码“内联”起来了。也就是说,编译器将使用相应的函数代码替换函数调用。对于内联代码,程序无需跳到另一个位置处执行代码,再跳回来。

        因此,内联函数的运行速度比常规函数稍快,但代价是需要占用更多内存。如果程序在10个不同的地方调用同一个内联函数,则该程序将包含该函数代码的 10 个副本。

        应有选择地使用内联函数。如果执行函数代码的时间比处理函数调用机制的时间长,则节省的时间将只占整个过程的很小一部分。如果代码执行时间很短,则内联调用就可以节省非内联调用使用的大部分时间。另一方面,由于这个过程相当快,因此尽管节省了该过程的大部分时间,但节省的时间绝对值并不大,除非该函数经常被调用。

        要使用这项特性,必须采取下述措施之一:
    1. 在函数声明前加上关键字inline;
    2. 在函数定义前加上关键字inline。

        通常的做法是省略原型,将整个定义(即函数头和所有函数代码) 放在本应提供原型的地方。

        程序员请求将函数作为内联函数时,编译器并不一定会满足这种要求。它可能认为该函数过大或注意到函数调用了自己(内联函数不能递归),因此不将其作为内联函数:而有些编译器没有启用或实现这种特性。

        示例通过内联函 square()(计算参数的平方)演示了内联技术,注意到整个函数定义都放在一行中,但并不一定非得这样做。然而,如果函数定义占用多行(假定没有使用冗长的标识符),则将其作为内联函数就不太合适。

示例源码:

// Len_inline.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//

#include <iostream>
using namespace std;
inline double square(double x)
{
	return x * x;
}
int main()
{
	double a, b;
	double c = 13.0;
	a = square(5.0);
	b = square(4.5 + 7.5);
	cout << "a = " << a << ", b = " << b << endl;
	cout << "c = " << c;
	cout << ", c squared = " << square(c++) << endl;
	cout << "Now c = " << c << endl;
}

执行结果:


输出表明,内联函数和常规函数一样,也是按值来传递参数的。如果参数为表达式,如 4.5.+ 7.5,则函数将传递表达式的值(这里为12)。这使得 C++的内联功能远远胜过C语言的宏定义。

尽管程序没有提供独立的原型,但 C++原型特性仍在起作用。这是因为在函数首次使用前出现的整个函数定义充当了原型。这意味着可以给 square()传递 int 或long 值,将值传递给函数前,程序自动将这个值强制转换为 double类型。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C++ 文件操作篇

C 文件操作篇 文章目录 C 文件操作篇1 简介1.1 继承关系1.2 流1.3 缓冲区输入输出流中的缓冲streambuf 2 文件操作步骤2.1 头文件2.2 创建流对象2.3 打开文件2.4 读取数据第一种&#xff1a;**按元素直接读**第二种&#xff1a;**使用getline按行读**第三种&#xff1a;**使用*…

数据结构--查找

目录 1. 查找的基本概念 2. 线性表的查找 3. 树表的查找 3.1 二叉排序树 3.1.1 定义: 3.1.2 存储结构&#xff1a; 3.1.3 二叉排序树的查找 3.1.4 二叉排序树的插入 3.1.5 二叉排序树删除 3.2 平衡二叉树&#xff08;AVL 3.2.1 为什么要有平衡二叉树 3.2.2 定义 3.3 B-树 3.3.1…

如何安装T4显卡的驱动

文章目录 一、没有驱动的报错现象二、cuda版本与驱动的版本对应关系三、安装驱动方法1&#xff1a;方法2&#xff1a; 一、没有驱动的报错现象 ERROR: Unable to find the kernel source tree for the currently running kernel. Please make sure you have installed the ker…

uniapp-android原生插件如何打aar包 (避坑指南二)

1.打开android studio项目&#xff0c;找到module项目&#xff0c;打开右侧gradle&#xff0c;找到对应的module, 点击assemble&#xff0c;会打包生成aar&#xff0c;生成的aar在 [module]/build/outputs/aar/目录下 特殊情况&#xff0c;如果右侧的gradle&#xff0c;找到mo…

生存分析序章2——生存分析之Python篇:lifelines库入门

目录 写在开头1. 介绍 lifelines 库1.1 lifelines库简介1.2 安装与环境配置 2. 数据准备2.1 数据格式与结构2.2 处理缺失数据2.3 对异常值的处理 3. Kaplan-Meier 曲线3.1 使用 lifelines 绘制生存曲线3.2 曲线解读3.3 额外补充 4. Cox 比例风险模型4.1 lifelines 中的 Cox 模型…

RabbitMq知识概述

本文来说下RabbitMq相关的知识与概念 文章目录 概述AMQP协议Exchange 消息如何保证100&#xff05;投递什么是生产端的可靠性投递可靠性投递保障方案 消息幂等性高并发的情况下如何避免消息重复消费confirm 确认消息、Return返回消息如何实现confirm确认消息return消息机制 消费…

Flask 与微信小程序对接

Flask 与微信小程序的对接 在 web/controllers/api中增建py文件&#xff0c;主要是给微信小程序使用的。 web/controllers/init.py # -*- coding: utf-8 -*- from flask import Blueprint route_api Blueprint( api_page,__name__ )route_api.route("/") def ind…

数据的价值:隐藏在数字背后的巨大财富

在当今数字化的时代&#xff0c;数据已经成为了一种宝贵的资源&#xff0c;它的价值被越来越多的人所认识。数据不仅可以帮助企业更好地了解市场和消费者&#xff0c;提高决策的准确性&#xff0c;还可以为社会带来更多的便利和创新。企业、组织和个人可以利用数据来更好地了解…

编程笔记 html5cssjs 004 我的第一个页面

编程笔记 html5&css&js 004 我的第一个页面 一、基本结构二、HTML标签三、HTML元素四、HTML属性五、编写第一个网页六、使用VSCODE小结 开始编写网页&#xff0c;并且使用第一个网页成为一个母板&#xff0c;用于完成后续内容的学习。有一个基本要求&#xff0c;显示结…

linux cat命令增加-f显示文件名功能

在使用cat命令配合grep批量搜索文件内容时&#xff0c;我仅仅能知道是否搜索到&#xff0c;不知道是在哪个文件里找到的。比如cat ./src/*.c | grep full_write,在src目录下的所有.c文件里找full_write,能匹配到所有的full_write&#xff0c;但是不知道它们分别在哪些文件里。于…

Spring Boot+RocketMQ 实现多实例分布式环境下的事件驱动

为什么要使用MQ&#xff1f; 在Spring Boot Event这篇文章中已经通过Guava或者SpringBoot自身的Listener实现了事件驱动&#xff0c;已经做到了对业务的解耦。为什么还要用到MQ来进行业务解耦呢&#xff1f; 首先无论是通过Guava还是Spring Boot自身提供的监听注解来实现的事…

【动画视频生成】

转自&#xff1a;机器之心 动画视频生成这几天火了&#xff0c;这次 NUS、字节的新框架不仅效果自然流畅&#xff0c;还在视频保真度方面比其他方法强了一大截。 最近&#xff0c;阿里研究团队构建了一种名为 Animate Anyone 的方法&#xff0c;只需要一张人物照片&#xff0…

观察者模式概述

观察者模式,它用于建立一种对象与对象之间的依赖关系&#xff0c; 一个对象发生改变将自动通知其他对象&#xff0c; 其他对象将相应做出反应。在观察者模式种&#xff0c;发生改变的对象称为观察目标&#xff0c; 而被通知的对象称为观察者&#xff0c;一个观察目标可以对应多…

【SD】IP-Adapter 进阶 - 画风融合【3】

生成图片大小&#xff1a;1024x576 将图片一的画风转到图片2中。 测试一&#xff1a; control-1:IP-Adapter 导入图片1 仅调整大小&#xff08;拉伸&#xff09; control-2:canny 导入图片2 仅调整大小&#xff08;拉伸&#xff09; best qualit…

FPGA高端项目:SDI 视频+音频编解码,提供工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐我这里已有的 GT 高速接口解决方案我目前已有的SDI编解码方案 3、设计思路和框架设计框图GV8601A均衡EQGTX 时钟要求GTX 调用与控制SMPTE SD/HD/3G-SDISMPTE SD/HD/3G-SDI 接收SMPTE SD/HD/3G-SDI 发送 SDI 视频接收数据处理SDI 音频接收-…

Mysql实时数据同步工具Alibaba Canal 使用

目录 Mysql实时数据同步工具Alibaba Canal 使用Canal是什么&#xff1f;工作原理重要版本更新说明 环境准备安装Canalwindow Java : Canal Client 集成依赖编码 工作流程其他学习canal资料 个人主页: 【⭐️个人主页】 需要您的【&#x1f496; 点赞关注】支持 &#x1f4af; M…

2024美赛数学建模思路A题B题C题D题E题F题思路汇总 选题分析

文章目录 1 赛题思路2 美赛比赛日期和时间3 赛题类型4 美赛常见数模问题5 建模资料 1 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 2 美赛比赛日期和时间 比赛开始时间&#xff1a;北京时间2024年2月2日&#xff08;周五&#xff…

excel 函数技巧

1&#xff1a;模糊查询 LOOKUP(1,0/FIND(F1062,Sheet1!C$2:Sheet1!C$9135),Sheet1!B$2:Sheet1!B$9135) 函数含义&#xff1a;寻找F列1062行和sheet1中的C2行到C9135行进行模糊查询&#xff0c;返回该行对应的B2行到B9135行的结果。未查到返回结果0 函数公式&#xff1a; LO…

leetcode贪心算法题总结(一)

此系列分三章来记录leetcode的有关贪心算法题解&#xff0c;题目我都会给出具体实现代码&#xff0c;如果看不懂的可以后台私信我。 本章目录 1.柠檬水找零2.将数组和减半的最少操作次数3.最大数4.摆动序列5.最长递增子序列6.递增的三元子序列7.最长连续递增序列8.买卖股票的最…

设计模式-过滤器模式

设计模式专栏 模式介绍模式特点应用场景Java中的过滤器介绍代码示例Java实现过滤器模式Python实现过滤器模式 过滤器模式在spring中的应用 模式介绍 过滤器模式是一种设计模式&#xff0c;它允许开发人员使用不同的标准来过滤一组对象。这种模式是通过运算逻辑以解耦的方式将它…