C++内联函数与引用(超详细)

文章目录

  • 前言
  • 一、内联函数
    • 1.为什么会存在内联函数
    • 2.什么是内联函数
    • 3.内联函数注意事项
  • 二、引用
    • 1.什么是引用
    • 2.引用的特性
    • 3.常引用
    • 4.引用使用场景
    • 5.引用与指针
  • 总结


前言

一、内联函数

1.为什么会存在内联函数

🧐🧐首先我们介绍内联函数之前,首先看一下我们之前学过的#define 定义的宏

写一个宏函数,实现两个函数的相加

#include <iostream>
using namespace std;#define ADD(x,y) ((x)+(y))
int main()
{int a = 10;int b = 20;cout << ADD(a,b) << endl;return 0;
}

想想我们当初学习宏函数的的优点和缺点
⚾⚾优点:这些函数我们也可以用函数来实现,但是函数调用需要开辟栈帧,浪费空间,
而宏就完美解决了这个问题,它会在调用它的地方展开。进行完全替换。
⚾⚾缺点:不能调试,使用起来复杂,没有安全类型的检查,代码可读性差

那我们可不可以实现一个专门的库函数,既包含宏的有点又避免了函数调用的缺点呢??
这时内联函数就出现了!!!

2.什么是内联函数

✨ ✨概念:用inline修饰的函数就是内联函数,编译时C++编译器会在调用的地方展开,没有函数调用建立栈帧的开销,提高程序运行效率。

int add(int x, int y)
{return x + y;
}
int main()
{int a = 10;int b = 20;int ret = add(a, b);cout << ret<< endl;return 0;
}

我们转到反汇编看一下这段代码

在这里插入图片描述

在正常情况下,没有加内联函数确实进行了函数调用建立栈帧。

我们加上内联函数再来看一下

在这里插入图片描述
我们发现怎末跟上面代码一样,都调用了add函数,建立了栈帧。这厮怎末回事???

这是因为在Debug模式下,方便调试,编译器默认不进行优化,也就是不进行展开,依然使用一般的函数调用。
我们对vs设置一下环境
在这里插入图片描述
可以看到,优化之后inline修饰过的函数会直接展开。

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

在这里插入图片描述

3.内联函数注意事项

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

🎇🎇内联函数对于编译器来说,只是一个建议,不同编译器关于inline实现机制可能不同,一般建议函数规模较小的,不是递归实现,调用频繁的采用内联函数修饰,否则编译器会忽略inline的特性

🎇🎇inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。

main.cpp

#include "add.h"
int main()
{int ret = add(10, 20);cout << ret<< endl;return 0;
}

add.cpp

#include "add.h"
inline int add(int x, int y)
{return x + y;
}

add.h

#include <iostream>
using namespace std;inline int add(int x, int y);

严重性 代码 说明 项目 文件 行 禁止显示状态
错误 LNK2019 无法解析的外部符号 “int __cdecl add(int,int)” (?add@@YAHHH@Z),函数 main 中引用了该符号 12_29 D:\study C\c嘎嘎\12_29\12_29\main.obj 1

我们一般建议把内联函数放在一个文件夹中进行处理

#include <iostream>
using namespace std;
inline int add(int x, int y)
{return x + y;
}
int main()
{int ret = add(10, 20);cout << ret<< endl;return 0;
}

二、引用

1.什么是引用

其实引用就是给变量取别名,这个别名和这个变量共用同一块空间。

使用:类型名 &别名=变量名; 对别名的改变同样也改变变量名的值

在这里插入图片描述

引用只能用于同类型变量才可以

在这里插入图片描述

2.引用的特性

引用时必须初始化

在这里插入图片描述

可以给一个变量取多个别名,也可以给别名起别名

在这里插入图片描述

引用一旦引用了一个实体,就不可以在引用其他实体

在这里插入图片描述

3.常引用

我们对引用加上const修饰后会发生什么呢???

权限不可以扩大,本来是const int 类型,现在变成了int类型

在这里插入图片描述
那我们如何进行修改呢??
只要在引用前边加上const就可以

这其实就是权限的平移,本来是一个const int 类型,现在变成了const int 。两个权限一致

在这里插入图片描述

深度理解临时变量

我们看一下这段代码
在这里插入图片描述

我们发现他出错了,但是为什么会出错呢??
有点人感觉这是类型不匹配导致的!!但其实并不是这样,他还有更深层次的理解

隐式类型转化,强转,截断都会发生产生临时变量,这个临时变量具有常性(不可被修改)

举个例子::
int a=10;double b=a;
这段代码肯定不会报错,会正常运行,但是他为什么可以实现呢???
本质是编译器把a那个变量进行了拷贝,产生了临时变量,通过这个临时变量取进行类型转化✨✨✨✨

权限既然不能放大,那我们可不可以缩小呢??
这个其实是可以的,我们来具体看一下

在这里插入图片描述

4.引用使用场景

作为函数参数,进行传参,避免指针的使用错误

我们来回忆一下之前c语言通过一个函数对两个变量进行交换,我们的形参必须用指针才可以实现,是不是很麻烦,那这时我们就可以用引用来实现了!!!

在这里插入图片描述
在这种场景下我们用引用就会非常方便

作为函数参数,进行传参,避免拷贝,提高程序运行效率

想想我们当时为什么会用指针来进行传参,比如我们传结构体传参,会生成一份原大小的拷贝,对资源浪费非常大。指针传参仅仅会拷贝4/8个字节,减少了空间的浪费。那我们也可以用引用来进行传参,南无连这个4/8个字节的拷贝也不需要了。
在这里插入图片描述

作为返回值,进行传参,避免拷贝,提高程序运行效率

我们知道调用函数,我们并不是返回的那个对象,而是那个对象那个的拷贝,我们也可以通过进行引用返回避免拷贝

在这里插入图片描述

作为返回值,我们还可以对返回值进行修改,做返回值如果出了作用于还在,可以用传引用返回,如果出了作用域就不在了(销毁了),那就不能用传引用返回,只能用传值返回

5.引用与指针

在语法概念上,我们知道,引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。

在这里插入图片描述

但是在底层上,我们会发现,引用也是用指针实现的

我们转到反汇编观察一下
在这里插入图片描述

🌟指针存储一个变量地址,而引用是一个变量的别名
🌟引用必须初始化,指针没有要求
🌟引用一旦引用了一个实体,就不可以再引用其他实体。地址可以在任何时候指向一个
同类型的实体
🌟只有空指针,没有空引用
🌟只有多级指针,没有多级引用
🌟引用+1是指向的变量大小进行加一,指针+1是跳过一个指向类型的大小的地址
🌟引用大小为引用实体的大小,而指针的大小是4/8字节
🌟访问方式不同,指针需要解引用访问,引用编译器自己处理
🌟引用使用起来比指针相对安全

总结

以上就是今天要讲的内容,本文仅仅详细介绍了C++内联函数与引用,希望对大家的学习有所帮助,仅供参考 如有错误请大佬指点我会尽快去改正 欢迎大家来评论~~ 😘 😘 😘 😘

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

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

相关文章

记一次JSF异步调用引起的接口可用率降低 | 京东云技术团队

前言 本文记录了由于JSF异步调用超时引起的接口可用率降低问题的排查过程&#xff0c;主要介绍了排查思路和JSF异步调用的流程&#xff0c;希望可以帮助大家了解JSF的异步调用原理以及提供一些问题排查思路。本文分析的JSF源码是基于JSF 1,7.5-HOTFIX-T6版本。 起因 问题背景…

基于 Vue3 和 WebSocket 实现的简单网页聊天应用

首先附上项目介绍,后面详细解释技术细节 1. chat-websocket 一个基于Vue3和WebSocket的简易网络聊天室项目&#xff0c;包括服务端和客户端部分。 项目地址 websocket-chat 下面是项目的主要组成部分和功能&#xff1a; 项目结构 chat-websocket/ |-- server/ # WebSocket 服…

Linux上管理不同版本的 JDK

当在 Linux 上管理不同版本的 JDK 时&#xff0c;使用 yum 和 dnf 可以方便地安装和切换不同的 JDK 版本。本文将介绍如何通过这两个包管理工具安装 JDK 1.8 和 JDK 11&#xff0c;并利用软连接动态关联这些版本。 安装 JDK 1.8 和 JDK 11 使用 yum 安装 JDK 1.8 打开终端并…

【AIGC表情prompt】提示词练习技巧

表情类提示词练习技巧 医疗机器人&#xff0c;男人笑脸景深&#xff0c;数据&#xff0c;座标&#xff0c;12k,c4d渲染&#xff0c;高分辨率&#xff0c;,暖色调&#xff0c;高清对比 医疗机器人&#xff0c;男人微笑&#xff0c;景深&#xff0c;数据&#xff0c;座标&#xf…

线上发布稳定性方案介绍

目录 一、方案说明 二、线上发布问题描述 2.1 无损上下线背景说明 2.1.1 服务⽆法及时下线 2.1.2 初始化慢 2.1.3 注册太早 2.1.4 发布态与运⾏态未对⻬ 三、问题解决方案 3.1 无损下线方案 3.1.1 什么是无损下线 3.1.2 传统解决方式 3.1.3 云原生场景解决方案 3.1…

提升爬虫IP时效:解决被封IP的难题

在进行数据采集时&#xff0c;经常会遇到被目标网站封禁IP的情况&#xff0c;这给爬虫系统带来了困扰。本文将介绍如何提升爬虫IP的时效&#xff0c;解决被封IP的难题&#xff0c;帮助您顺利进行数据采集&#xff0c;不再受限于IP封禁。 第一步&#xff1a;使用爬虫IP 使用爬虫…

使用element中el-cascader级联选择器实现省市区街道筛选(非动态加载)

<template><el-form ref"form" :model"form" label-width"80px"><el-form-item label"地址:" prop"addressList"><el-cascaderv-model"form.addressList":props"props":options&q…

《网络是怎样连接的》2.1节图表(自用)

图3.1&#xff1a;协议栈的组成 图3.2&#xff1a;netstat命令查看套接字 上图中每一行就是一个套接字 图3.3&#xff1a;协议栈在浏览器访问DNS服务器与web服务器时的具体工作流程 套接字由协议栈创建 应用程序通过Socket库中的程序组件与协议栈交互

飞企互联-FE企业运营管理平台 登录绕过漏洞复现

0x01 产品简介 飞企互联-FE企业运营管理平台是一个基于云计算、智能化、大数据、物联网、移动互联网等技术支撑的云工作台。这个平台可以连接人、链接端、联通内外&#xff0c;支持企业B2B、C2B与O2O等核心需求&#xff0c;为不同行业客户的互联网转型提供支持。 0x02 漏洞概…

图像拼接——基于homography的特征匹配算法

目录 1. 任务要求2. 数据集3. 基于homography的特征匹配算法4. 拼接流程展示4.1 图片实例4.2 特征点位图4.3 特征点匹配结果4.4 相机校准结果4.5 拼接结果 5. 部分图像拼接结果展示 1. 任务要求 输入&#xff1a;同一个场景的两张待拼接图像&#xff08;有部分场景重合&#x…

2023年03月18日_微软office365 copilot相关介绍

文章目录 Copilot In WordCopilot In PowerpointCopilot In ExcelCopilot In OutlookCopilot In TeamsBusiness Chat1 - copilot in word2 - copilot in excel3 - copilot in powerpoint4 - copilot in outlook5 - copilot in teams6 - business chat word 1、起草草稿 2、自动…

命令模式-举例

开关和电灯之间并不存在直接耦合关系&#xff0c;在命令模式中&#xff0c;发送者与接收者之间引入了新的命令对象&#xff0c;将发送者的请求封装在命令对象中&#xff0c;再通过命令对象来调用接收者的方法。 命令模式的主要缺点如下&#xff1a; 使用命令模式可能会导致某…

自然语言处理2——轻松入门情感分析 - Python实战指南

目录 写在开头1.了解情感分析的概念及其在实际应用中的重要性1.1 情感分析的核心概念1.1.1 情感极性1.1.2 词汇和上下文1.1.3 情感强度1.2 实际应用中的重要性 2. 使用情感分析库进行简单的情感分析2.1 TextBlob库的基本使用和优势2.1.1 安装TextBlob库2.1.2 文本情感分析示例2…

二、RK3588-安装Opencv-4.8.1(C++版本)

1.前言 OpenCV是一个跨平台的计算机视觉和机器学习软件库&#xff0c;基于Apache2.0许可&#xff08;开源&#xff09;发行。它可以在Linux、Windows、Android和Mac OS操作系统上运行。OpenCV由一系列C函数和少量C类构成&#xff0c;同时提供了Python、Ruby、MATLAB等语言的接口…

Stimulsoft BI Designer 2024.1.2 Crack

Stimulsoft BI Designer Do you want to create reports and dashboards, but you do not need to create your application? We want to offer you a great solution – Stimulsoft Designer! All you need is to connect your data, drag it onto the template page, config…

Java日期和时间(一)

传统的日期和时间 Date 代表的是日期和时间 构造器说明public Date&#xff08;&#xff09;创建一个Date对象&#xff0c;代表的是系统当前此刻日期时间public Date&#xff08;long time&#xff09;把时间毫秒值转换成Date日期对象 import java.util.Date;public class …

weston 源码下载及编译

文章目录 前言一、安装 meson1. ubuntu 上安装pip32. 使用pip3安装meson3. 安装 ninja二、获取weston 源码三、编译 weston 源码1. meson build2. ninja -C build3. 安装编译生成的weston四、执行编译生成的weston总结参考资料前言 本文主要介绍 weston 9.0源码的下载和编译,…

DolphinScheduler 介绍及系统架构

目录 一、DolphinScheduler 介绍 1.1 关于 DolphinScheduler 1.2 特性 简单易用 丰富的使用场景 High Reliability High Scalability 1.3 名词解释 1.3.1 名词解释 1.3.2 模块介绍 二、DolphinScheduler 系统架构 2.1 系统架构图 2.2 架构说明 MasterServer 该服…

Mybatis插件入门

专栏精选 引入Mybatis Mybatis的快速入门 Mybatis的增删改查扩展功能说明 mapper映射的参数和结果 Mybatis复杂类型的结果映射 Mybatis基于注解的结果映射 Mybatis枚举类型处理和类型处理器 再谈动态SQL Mybatis配置入门 Mybatis行为配置之Ⅰ—缓存 Mybatis行为配置…

Java:IO流——字节流和字符流

目录 IO流的基本概念 IO流体系结构 FileOutputStream字节输出流 构造方法 成员方法 细节 关流 FileInputStream字节输入流 构造方法及成员方法 read不带参数代码示例 read带参数代码示例​编辑 将字节数组或字符数组转成字符串 FileReader 字符输入流 构造方法和…