初识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,一经查实,立即删除!

相关文章

【软考速通笔记】系统架构设计师⑤——软件工程基础知识

文章目录 一、前言二、基础知识点2.1 软件危机2.2 软件生命周期 三、软件过程模型&#xff08;论文&#xff09;3.1 瀑布模型3.2 原型模型3.3 螺旋模型3.4 敏捷模型3.5 软件统一过程模型3.6 软件成熟度模型3.7 软件成熟度模型集成 四、需求工程五、软件测试5.1 根据程序执行状态…

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

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

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

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

8、运算符

1、运算符相关概念 运算符&#xff1a; 具有一定运算规则的符号 运算符分类&#xff1a; 按照功能分&#xff1a; 赋值运算符 算术运算符 关系运算符 逻辑运算符 其他运算符 位运算符 按照操作数分&#xff1a; 单目运算符 双目运算符 三目运算符 表达式 具有一定意义的式子&…

【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…

算法训练营day08(字符串01:反转字符串,反转字符串2,替换数字,反转字符串里的单词,右旋转字符串)

第四章 字符串part01今日任务 ● 344.反转字符串 ● 541. 反转字符串II ● 卡码网&#xff1a;54.替换数字 ● 151.翻转字符串里的单词 ● 卡码网&#xff1a;55.右旋转字符串详细布置 344.反转字符串 建议&#xff1a; 本题是字符串基础题目&#xff0c;就是考察 reverse 函数…

Java中三种常用布局方式

引言 在Java Swing和JavaFX中&#xff0c;布局管理器&#xff08;Layout Managers&#xff09;用于控制组件&#xff08;如按钮、文本框等&#xff09;在容器&#xff08;如窗口、面板等&#xff09;内的位置和大小。下面介绍Java Swing中常用的三种布局方式&#xff1a; 1. Fl…

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

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

Leetcode(快慢指针习题思路总结,持续更新。。。)

这种模式&#xff0c;有一个非常出门的名字&#xff0c;叫龟兔赛跑。这种算法的两个指针的在数组上&#xff08;或是链表上&#xff0c;序列上&#xff09;的移动速度不一样。快的一个指针肯定会追上慢的一个&#xff08;可以想象成跑道上面跑得快的人套圈跑得慢的人&#xff0…

基于时间维度优化“开源 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. 示例代…

二刷代码随想录第15天

513. 找树左下角的值 找到深度最大的点&#xff0c;遍历方式左边节点在右边节点前面&#xff0c;找到就返回&#xff0c;一定就是最左下角的值了 class Solution { public:int max_depth -1;int result 0;int findBottomLeftValue(TreeNode* root) {traversal(root, 0);ret…

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的值&#…

Python plotly库介绍

一、引言 在数据可视化领域&#xff0c;Python提供了众多强大的库。其中&#xff0c;plotly是一个功能强大、交互式的可视化库&#xff0c;可以创建各种类型的图表&#xff0c;包括线图、散点图、柱状图、饼图、3D图表等。它不仅提供了美观的可视化效果&#xff0c;还支持交互式…

中国高铁、中兴通讯和中国 装备制造业的发展中能分别获得哪些启示

题目 【2015 年国考省级以上第四题】阅读“给定资料 4”,谈谈你从中国高铁、中兴通讯和中国装备制造业的发展中能分别获得哪些启示。(20 分) 要求&#xff1a;(1)紧扣材料,重点突出&#xff1b;(2)观点明确,表述有条理&#xff1b;(3)不超过 500 字。 材料 材料4&#xff1a…

Java全栈开发:宠物医院管理系统项目实战

Java全栈开发:宠物医院管理系统项目实战 项目介绍 本文将介绍一个基于Spring Boot + Vue.js的宠物医院管理系统的开发过程。该系统主要用于帮助宠物医院管理日常运营,包括患者管理、预约挂号、处方开具等功能。 技术栈 后端技术 Spring Boot 2.7.xSpring SecurityMyBatis…

BERT的中文问答系统36-2

为了使聊天机器人在生成答案时不依赖于特定的训练数据集&#xff0c;我引入其他方法来生成答案。例如&#xff0c;可以使用预训练的语言模型&#xff08;如BERT&#xff09;直接生成答案&#xff0c;或者使用搜索引擎来获取答案。以下BERT的中文问答系统36-1改进后的代码 1.引入…

升级智享 AI 直播三代:领航原生直播驶向自动化运营新航道

在瞬息万变的数字商业世界&#xff0c;直播行业恰似一艘破浪前行的巨轮&#xff0c;原生直播作为初始 “航船”&#xff0c;在历经风雨后&#xff0c;终于迎来智享 AI 直播三代这股强劲 “东风”&#xff0c;校准航向&#xff0c;开启自动化运营的全新航道&#xff0c;驶向一片…