初识C++:指针与引用的异同,inline关键字

大家好,我是小卡皮巴拉

文章目录

目录

一.指针和引用的关系

1.1 概念

1.2 相似点

1.3 不同点

二.inline关键字

2.1 概念

2.2 工作原理

2.3 使用场景

2.4 注意事项

三.nullptr

3.1 引入背景

3.2 语义和类型

3.3 使用场景

兄弟们共勉 !!! 


每篇前言

博客主页:小卡皮巴拉

咱的口号:🌹小比特,大梦想🌹

作者请求:由于博主水平有限,难免会有错误和不准之处,我也非常渴望知道这些错误,恳请大佬们批评斧正。

在上一次的博客初识C++:C++入门基础中,我们学习了引用,这是与C语言中的指针极其类似的语法结构,可以在一定程度上替代指针,下面我们来看看指针和引用有什么区别。

一.指针和引用的关系

1.1 概念

  • 指针指针是一个变量,其值为另一个变量的地址。在 C++ 中,通过使用*操作符来声明一个指针变量。例如,int *p;声明了一个名为p的指针,它可以指向一个int类型的变量。指针可以被重新赋值,让它指向不同的变量。

  • 引用引用是一个别名,它是一个变量的另一个名字。在 C++ 中,通过使用&操作符来声明一个引用。例如,int a = 10; int &r=a;,这里r就是a的引用,ra代表同一个变量,对r的操作就是对a的操作。

1.2 相似点

  • 访问变量内容

    • 指针和引用都可以用来访问所关联变量的内容对于指针,需要使用解引用操作符*来获取指针所指向变量的值。例如,如果p是一个指向int变量的指针,*p就可以获取指针所指向的int值。对于引用,直接使用引用名就可以访问它所关联变量的值,如上述例子中的r,它和a的值相同,使用r就相当于使用a

  • 函数参数传递效率提升方面(部分情况)

    • 在函数参数传递中,指针和引用都可以用来避免不必要的变量拷贝,提高效率。例如,当传递一个大型结构体作为函数参数时,使用指针或者引用可以避免整个结构体的拷贝。如果有一个函数void func(int *p)void func(int &r)当调用这些函数时,传递的是变量的地址或者别名,而不是变量的副本。

1.3 不同点

  • 初始化要求

    • 指针可以在声明后不立即初始化,它可以先定义为一个空指针(在 C++ 中nullptr是更好的表示空指针的方式),例如int *p = nullptr;,然后在后续的代码中再让它指向一个有效的变量。引用必须在声明时就进行初始化,并且一旦初始化后,就不能再绑定到其他变量例如,int a = 10; int &r=a;是正确的,但是不能在之后再将r绑定到其他变量,如r = b(假设b是另一个int变量)这种操作是不允许的。

  • 内存占用和操作灵活性

    • 指针本身占用内存空间,其大小通常取决于系统的寻址位数。例如,在 32 位系统中,指针大小一般是 4 字节,在 64 位系统中,指针大小一般是 8 字节。指针可以进行算术运算,如p++(假设p是一个指针)可以让指针指向下一个内存位置(如果p指向一个数组元素,那么它会指向下一个数组元素)引用在语法上只是一个别名,它本身不占用额外的内存空间(在底层实现上可能会有一些细微差异,但从用户角度可以这样理解),并且不能进行像指针那样的算术运算。

  • 重新赋值特性

    • 指针可以被重新赋值,使其指向不同的变量或者内存位置。例如,int a = 10, b = 20; int *p=&a; p = &b;是合法的,这样p就从指向a变成了指向b引用一旦初始化绑定到一个变量后,就不能被重新赋值去引用其他变量。例如,int a = 10, b = 20; int &r=a; r = b;这里并不是让r引用b,而是把b的值赋给r所引用的变量ar始终引用a

二.inline关键字

2.1 概念

在 C++ 中,inline是一个关键字,用于建议编译器将函数体直接插入到函数调用的地方,而不是像普通函数那样通过函数调用的机制(如栈帧的创建、参数传递、返回地址保存等)来执行函数。这样做的目的主要是为了提高程序的执行效率,减少函数调用的开销。例如:

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

这里的add函数被声明为inline函数,编译器可能会将函数体直接插入到调用add函数的地方。

2.2 工作原理

当编译器遇到inline函数调用时,它会尝试在编译阶段将函数的代码直接复制到调用点。这样,在程序执行时,就好像是直接在调用点执行了函数体的代码,而不是进行传统的函数调用过程。例如,如果有以下代码:

int main() {int x = 3, y = 5;int result = add(x, y);return 0;
}

编译器可能会将add函数的代码return a + b;直接替换到result = add(x, y);这个调用位置,就像写成了int result = x + y;一样。不过,这只是一种可能的优化方式,编译器是否真正执行这种优化取决于编译器的实现和优化策略。

2.3 使用场景

频繁调用的小型函数inline函数非常适合那些短小且被频繁调用的函数。例如,简单的数学运算函数(如加法、减法函数)或者获取和设置类成员变量的访问函数。这些函数的代码通常比较简短,将它们内联可以减少函数调用的开销,从而提高程序的性能。

class Rectangle {
private:int width;int height;
public:// 内联的获取函数inline int getWidth() const {return width;}// 内联的设置函数inline void setWidth(int w) {width = w;}
};

2.4 注意事项

代码膨胀过度使用inline可能会导致代码膨胀。因为每次函数被调用时,函数体的代码都会被插入到调用点,如果inline函数的代码很长或者被频繁调用,那么最终的可执行文件可能会变得很大。例如,一个有大量代码的inline函数在多个地方被调用,会导致程序中存在很多重复的代码。

编译器的决定权inline只是对编译器的一个建议,编译器并不一定会按照要求将函数内联。编译器会根据自己的优化策略、函数的复杂程度、调用频率等因素来决定是否真正内联一个函数。例如,一个包含复杂循环或者递归的函数,即使被声明为inline,编译器可能也不会将其内联,因为这样可能会导致代码变得更加难以优化或者不符合内联的实际效益。

三.nullptr

3.1 引入背景

在 C++ 早期版本中,使用NULL来表示空指针。NULL通常被定义为((void*)0),这在 C 语言中工作得很好。然而,在 C++ 中存在函数重载的情况,NULL的这种定义可能会导致一些问题。例如,假设有两个函数重载:void func(int)void func(void*),当调用func(NULL)时,编译器可能会产生歧义,因为NULL既可以被解释为整数0(对于int参数的函数),也可以被解释为void*类型的空指针(对于void*参数的函数)。为了解决这个问题,C++ 11 引入了nullptr

3.2 语义和类型

nullptr是一个表示空指针的常量。它的类型是std::nullptr_t,这是一种特殊的类型,能够隐式地转换为任何指针类型,但不能转换为非指针类型(除了boolnullptr转换为bool时为false)。例如:

int* p = nullptr;  // 正确,nullptr可以转换为int*
int i = nullptr;   // 错误,nullptr不能转换为int
if (nullptr) {     // 条件为假,因为nullptr转换为bool为false// 不会执行
}

3.3 使用场景

初始化指针变量在声明指针变量时,可以使用nullptr来初始化它,表示这个指针当前不指向任何有效的内存地址。这比使用NULL更加安全和明确,避免了上述提到的函数重载的歧义问题。

class MyClass {
public:void* ptr = nullptr;
};

作为函数参数传递空指针:当一个函数的参数是指针类型,并且需要传递一个表示 “没有指向任何东西” 的参数时,可以使用nullptr。例如:

void printString(const char* str) {if (str == nullptr) {std::cout << "字符串为空" << std::endl;} else {std::cout << str << std::endl;}
}

在指针比较中的应用可以使用nullptr来检查指针是否为空,就像以前使用NULL一样,但是更加符合 C++ 的类型系统。 

兄弟们共勉 !!! 

码字不易,求个三连

抱拳了兄弟们!

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

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

相关文章

DICOM医学影像应用篇——伪彩色映射 在DICOM医学影像中的应用详解

目录 引言 伪彩色映射的概念 基本原理 查找表&#xff08;Look-Up Table, LUT&#xff09; 步骤 示例映射方案 实现伪彩色映射的C代码 代码详解 伪彩色处理效果展示 总结 扩展知识 LUT 的基本概念 LUT 在伪彩色映射中的应用 示例 引言 在医学影像处理中&#xff0c…

韦东山stm32hal库--定时器喂狗模型按键消抖原理+实操详细步骤

一.定时器按键消抖的原理: 按键消抖的原因: 当我们按下按键的后, 端口从高电平变成低电平, 理想的情况是, 按下, 只发生一次中断, 中断程序只记录一个数据. 但是我们使用的是金属弹片, 实际的情况就是如上图所示, 可能会发生多次中断,难道我们要记录3/4次数据吗? 答:按键按下…

【Linux网络编程】第二弹---Socket编程入门指南:从IP、端口号到传输层协议及编程接口全解析

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】【Linux系统编程】【Linux网络编程】 目录 1、Socket 编程预备 1.1、理解源 IP 和目的 IP 1.2、认识端口号 1.2.1、端口号范围划分 1.2.2、理解 &q…

如何借助AI生成PPT,让创作轻松又高效

PPT是现代职场中不可或缺的表达工具&#xff0c;但同时也可能是令人抓狂的时间杀手。几页幻灯片的制作&#xff0c;常常需要花费数小时调整字体、配色与排版。AI的飞速发展为我们带来了革新——AI生成PPT的技术不仅让制作流程大大简化&#xff0c;还重新定义了效率与创意的关系…

基于时间维度优化“开源 AI 智能名片 S2B2C 商城小程序”运营策略:提升触达与转化效能

摘要&#xff1a; 随着数字化商业生态的蓬勃发展&#xff0c;“开源 AI 智能名片 S2B2C 商城小程序”融合前沿技术与创新商业模式&#xff0c;为企业营销与业务拓展带来新机遇。本文聚焦于用户时间场景维度&#xff0c;深入剖析如何依据不同时段用户行为特征&#xff0c;精准适…

【消息序列】详解(8):探秘物联网中设备广播服务

目录 一、概述 1.1. 定义与特点 1.2. 工作原理 1.3. 应用场景 1.4. 技术优势 二、截断寻呼&#xff08;Truncated Page&#xff09;流程 2.1. 截断寻呼的流程 2.2. 示例代码 2.3. 注意事项 三、无连接外围广播过程 3.1. 设备 A 启动无连接外围设备广播 3.2. 示例代…

vue3的prop

- 父组件需要传多个值给子组件 把值放对象&#xff0c;通过v-bind传整个对象 父组件 <script setup> import BlogPost from ./BlogPost.vue import { reactive } from vue; // 要传给子组件的所有值&#xff0c;用reactive包了该对象后&#xff0c;父组件的值变了&#…

Ubuntu下的Doxygen+VScode实现C/C++接口文档自动生成

Ubuntu下的DoxygenVScode实现C/C接口文档自动生成 1、 Doxygen简介 Doxygen 是一个由 C 编写的、开源的、跨平台的文档生成系统。最初主要用于生成 C 库的 API 文档&#xff0c;但目前又添加了对 C、C#、Java、Python、Fortran、PHP 等语言的支持。其从源代码中提取注释&…

uniapp强制修改radio-group内单选组件的状态方法

在uniapp开发中&#xff0c;需要在radio-group内部切换时做判断&#xff0c;提醒客户是否要变换radio的值&#xff0c;但是大家知道radio是单选组件&#xff0c;往往你点击后&#xff0c;是不能再修改状态的&#xff0c;就算你在点击后做判断&#xff0c;修改current的值&#…

数据结构-最短路径问题

一.问题分类 二.无权图单源最短路算法 dist[]数组记录的是个个顶点到源点的距离这个数组的下标表示顶点 源点到自己的距离是0,dist[s]0 path[]数组记录的是这个顶点的前驱&#xff0c;可以同过这个数组找到源点到个个顶点的距离 代码如下 void Unweighted(MGraph Graph, Ver…

Vue.js 实现用户注册功能

在本篇博客中&#xff0c;我们将通过一个简单的例子来展示如何使用 Vue.js 来实现一个用户注册功能。我们将创建一个包含用户名、邮箱和密码输入的表单&#xff0c;并在用户点击“创建账号”按钮时进行简单的验证。 完整代码 <!DOCTYPE html> <html lang"en&q…

【Java 学习】面向程序的三大特性:封装、继承、多态

引言 1. 封装1.1 什么是封装呢&#xff1f;1.2 访问限定符1.3 使用封装 2. 继承2.1 为什么要有继承&#xff1f;2.2 继承的概念2.3 继承的语法2.4 访问父类成员2.4.1 子类中访问父类成员的变量2.4.2 访问父类的成员方法 2.5 super关键字2.6 子类的构造方法 3. 多态3.1 多态的概…

impala入门与实践

1.impala基本介绍 impala是cloudera提供的一款高效率的sql查询工具&#xff0c;提供实时的查询效果&#xff0c;官方测试性能比hive快10到100倍&#xff0c;其sql查询比sparkSQL还要更加快速&#xff0c;号称是当前大数据领域最快的查询sql工具。impala是参照谷歌的新三篇论文…

结构方程模型(SEM)入门到精通:lavaan VS piecewiseSEM、全局估计/局域估计;潜变量分析、复合变量分析、贝叶斯SEM在生态学领域应用

目录 第一章 夯实基础 R/Rstudio简介及入门 第二章 结构方程模型&#xff08;SEM&#xff09;介绍 第三章 R语言SEM分析入门&#xff1a;lavaan VS piecewiseSEM 第四章 SEM全局估计&#xff08;lavaan&#xff09;在生态学领域高阶应用 第五章 SEM潜变量分析在生态学领域…

小米PC电脑手机互联互通,小米妙享,小米电脑管家,老款小米笔记本怎么使用,其他品牌笔记本怎么使用,一分钟教会你

说在前面 之前我们体验过妙享中心&#xff0c;里面就有互联互通的全部能力&#xff0c;现在有了小米电脑管家&#xff0c;老款的笔记本竟然用不了&#xff0c;也可以理解&#xff0c;毕竟老款笔记本做系统研发的时候没有预留适配的文件补丁&#xff0c;至于其他品牌的winPC小米…

python爬虫案例——猫眼电影数据抓取之字体解密,多套字体文件解密方法(20)

文章目录 1、任务目标2、网站分析3、代码编写1、任务目标 目标网站:猫眼电影(https://www.maoyan.com/films?showType=2) 要求:抓取该网站下,所有即将上映电影的预约人数,保证能够获取到实时更新的内容;如下: 2、网站分析 进入目标网站,打开开发者模式,经过分析,我…

一分钟食用前端测试框架Jest

安装 其实食用Jest是很简单的,我们只需要安装Jest即可 npm install --save-dev jestyarn add --dev jestpnpm add --save-dev jest ESmodule 本身来说,Jest是不支持Esmodule的,他支持CommonJS,我们需要Babel改一下 npm i --save-dev babel-jest babel/core babel/preset-env …

从 App Search 到 Elasticsearch — 挖掘搜索的未来

作者&#xff1a;来自 Elastic Nick Chow App Search 将在 9.0 版本中停用&#xff0c;但 Elasticsearch 拥有你构建强大的 AI 搜索体验所需的一切。以下是你需要了解的内容。 生成式人工智能的最新进展正在改变用户行为&#xff0c;激励开发人员创造更具活力、更直观、更引人入…

若依框架部署在网站一个子目录下(/admin)问题(

部署在子目录下首先修改vue.config.js文件&#xff1a; 问题一&#xff1a;登陆之后跳转到了404页面问题&#xff0c;解决办法如下&#xff1a; src/router/index.js 把404页面直接变成了首页&#xff08;大佬有啥优雅的解决办法求告知&#xff09; 问题二&#xff1a;退出登录…

【贪心算法第六弹——334.递增的三元子序列(easy)】

目录 1.题目解析 题目来源 测试用例 2.算法原理 3.实战代码 代码解析 本题属于最长递增子序列的简化版本&#xff0c;只需要判断能不能组成三位的递增子序列即可&#xff0c;建议先去看博主的另一篇博客可以更好的理解本篇博客&#xff1a;300.最长递增子序列 1.题目解析…