【C++】C++入门基础--引用,inline,nullptr

文章目录

  • 前言
  • 一、引用?
    • 1.1 引用的概念和定义
    • 1.2 引用的特性
    • 1.3 引用的使用
    • 1.4 const引用(常引用)
    • 1.5 指针和引用的关系
  • 二、inline
    • 2.1inline概念和定义
    • 2.2 inline使用
    • 2.3 inline注意事项
  • 三.nullptr
  • 总结


在这里插入图片描述

前言

上一篇文章我们介绍了C++中的命名空间,函数重载,缺省参数等内容,今天我们主要介绍引用,inline和nullptr的内容,也属于C++中比较基础但重要的内容。


一、引用?

1.1 引用的概念和定义

引用(reference)就是C++对C语言的重要扩充。引用就是某一变量(目标)的一个别名,对引用的操作与对变量直接操作完全一样。
引用的声明方法:
类型标识符 &引用名=目标变量名;
引用引入了对象的一个同义词。定义引用的表示方法与定义指针相似,只是用&代替了*。C++中为了避免引入太多的运算符,会复用C语言的一些符号,比如如前面的<<和>>,这里引用也和取地址使用了同⼀个符号&,大家注意使用方法角度区分就可以

int main()
{
	int a = 10;
	int& b = a;//b是a的别名
	int& c = b;//c是b的别名
	c++;//c++同时b和a都++
	cout << a << endl;
	cout << b << endl;
	cout << c << endl;
	return 0;
}

在这里插入图片描述
如果我们看他们的地址会发现,他们是一样的
在这里插入图片描述

1.2 引用的特性

(1)&在此不是求地址运算,而是起标识作用。
(2)类型标识符是指目标变量的类型。
(3)声明引用时,必须同时对其进行初始化。
(4)引用声明完毕后,相当于目标变量名有两个名称,即该目标原名称和引用名,且不能再把该引用名作为其他变量名的别名。

//以下写法都是不对的
int main()
{
	int& ra;//未初始化
	int a = 10;
	int b = 20;
	int& rb = a;
	int& rb = b;//引用多个对象
}

1.3 引用的使用

• 引用在实践中主要是于引用传参和引用做返回值中减少拷贝提高效率和改变引用对象时同时改变被引用对象。

• 引用传参跟指针传参功能是类似的,引用传参相对更方便⼀些。

• 引用和指针在实践中相辅相成,功能有重叠性,但是各有特点,互相不可替代。C++的引用跟其他语言的引用(如Java)是有很大的区别的,除了用法,最大的点,C++引用定义后不能改变指向,Java的引用可以改变指向。

• 使用C++引用替代指针传参,目的是简化程序,避开复杂的指针。

void Swap(int& a, int& b)
{
	int tmp = a;
	a = b;
	b = tmp;
}

int main()
{
	int a = 10;
	int b = 20;
	Swap(a, b);
	cout << a << endl;
	cout << b << endl;
	return 0;
}

在这里插入图片描述
之前我们用C语言想写一个交换函数需要传递指针才能改变实参,但是在这里,我们传递实参的别名,用引用的方式,不传指针也能直接改变实参。

typedef struct ListNode
{
 int val;
 struct ListNode* next;
}LTNode, *PNode;
// 指针变量也可以取别名,这⾥LTNode*& phead就是给指针变量取别名
// 这样就不需要⽤⼆级指针了,简化了程序
//void ListPushBack(LTNode** phead, int x)
//void ListPushBack(LTNode*& phead, int x)

1.4 const引用(常引用)

常引用声明方式:const 类型标识符&引用名=目标变量名
用这种方式声明的引用,不能通过引用对目标变量的值进行修改,从而使引用的目标成为const,达到了引用的安全性

  1. 使用const定义的变量只能用使用const定义的别名,无const的变量,别名视情况加const。总的来说就是权限可以缩小但是不能放大。
    int a = 10;
	const int& ra = a;//引用正确,ra使用const只读不写,访问权限缩小

	const int a = 10;
	const int& ra = 10;//引用正确,ra和a都是只读不写。

	const int a = 10;
	int& ra = a;//引用错误,ra可以进行写操作,权限增大
  1. 需要注意的是类似 int& rb = a * 3; double d = 12.34; int& rd = d; 这样⼀些场景下a*3的和结果保存在⼀个临时对象中, int& rd = d 也是类似,在类型转换中会产生临时对象存储中间值,也就是时,rb和rd引用的都是临时对象,而C++规定临时对象具有常性,所以这⾥就触发了权限放大,必须要用常引用才可以。
 int a = 10;
 const int& ra = 30;
 
 //int& rb=a*3  错误,a*3属于临时变量需要加const
 const int& rb = a*3;//正确
 double d = 12.34;
 // 编译报错:“初始化”: ⽆法从“double”转换为“int &”
 // int& rd = d;  发生截断,相当于把截断后的变量存入一个临时变量,用const修饰
 const int& rd = d;//正确
 return 0;

所谓临时对象就是编译器需要⼀个空间暂存表达式的求值结果时临时创建的⼀个未命名的对象,C++中把这个未命名对象叫做临时对象。

1.5 指针和引用的关系

C++中的指针和引用是相互有重合,也相互有不同两个概念。在真实的实践中他们相辅相成,不能相互取代。

  • 从内存空间上看,引用只是给原来的变量取了一个别名,其并不开辟内存空间,而指针需要存储一个变量的地址,需要开辟空间。
  • 引用必须初始化,指针可以不初始化(只是建议初始化)。
  • 引用只能指定一个对象,指针可以改变指向。
  • 引用可以直接控制原来的变量,指针需要解引用才能控制原变量。
  • sizeof的结果不一样,引用的结果是原变量的大小,指针的结果是地址空间所占的字节个数。
  • 指针容易出现野指针,空指针的问题。引用不容易出现这些问题,相对安全。

二、inline

2.1inline概念和定义

inline是C++关键字,在函数声明或定义中,函数返回类型前加上关键字inline,即可以把函数指定为内联函数。这样可以解决一些频繁调用的函数大量消耗栈空间(栈内存)的问题。关键字inline必须与函数定义放在一起才能使函数成为内联函数,仅仅将inline放在函数声明前面不起任何作用。inline是一种“用于实现”的关键字,而不是一种“用于声明”的关键字。

inline的出现一定程度上取代了C语言中宏函数。C中的宏函数经常会因为少加括号等问题而得不到正确的答案。

2.2 inline使用

在使用inline时只需要在定义函数前面加上inline即可

inline int Add(int x, int y)
{
 int ret = x + y;
 ret += 1;
 ret += 1;
 ret += 1;
 return ret;
}
int main()
{
 int ret = Add(1, 2);
 cout << Add(1, 2) * 5 << endl;
 return 0;
}

2.3 inline注意事项

内联是以代码膨胀复制为代价,仅仅省去了函数调用的开销,从而提高函数的执行效率。如果执行函数体内代码的时间,相比于函数调用的开销较大,那么效率的收获会很少。另一方面,每一处内联函数的调用都要复制代码, 将使程序的总代码量增大,消耗更多的内存空间。以下情况不宜使用内联:
1)如果函数体内的代码比较长,使用内联将导致内存消耗代价较高。
2)如果函数体内出现循环,那么执行函数体内代码的时间要比函数调用的开销大。

inline对于编译器而言只是⼀个建议,也就是说,你加了inline编译器也可以选择在调用的地方不展开,不同编译器关于inline什么情况展开各不相同,因为C++标准没有规定这个。inline适用于频繁调⽤的短小函数,对于递归函数,代码相对多⼀些的函数,加上inline也会被编译器忽略。

vs编译器debug版本下面默认是不展开inline的,这样方便调试,debug版本想展开需要设置⼀下以下两个地方。
在这里插入图片描述
在这里插入图片描述

inline不建议声明和定义分离到两个文件,分离会导致链接错误。因为inline被展开,就没有函数地址,链接时会出现报错。

三.nullptr

在C语言中NULL是一个宏,其定义如下

#ifndef NULL
    #ifdef __cplusplus
       #define NULL 0
    #else
       #define NULL ((void *)0)
    #endif
#endif

C++中NULL可能被定义为字面常量0,或者C中被定义为无类型指针(void*)的常量。不论采取何种定义,在使用空值的指针时,都不可避免的会遇到⼀些麻烦,本想通过f(NULL)调用指针版本的f(int*)函数,但是由于NULL被定义成0,调用了f(int* x),因此与程序的初衷相悖。f((void*)NULL);调用会报错。

void f(int x)
{
	cout << "f(int x)" << endl;
}
void f(int* ptr)
{
	cout << "f(int* ptr)" << endl;
}
int main()
{
	f(0);
	f(NULL);
	f((int*)NULL);
	f(nullptr);
	return 0;
}

在这里插入图片描述
C++11中引入nullptr,nullptr是⼀个特殊的关键字,nullptr是⼀种特殊类型的字面量,它可以转换成任意其他类型的指针类型。使用nullptr定义空指针可以避免类型转换的问题,因为nullptr只能被隐式地转换为指针类型,而不能被转换为整数类型。

总结

以上就是今天的全部内容,主要介绍了一些C++的基础内容,C++的内容还有许多,如果喜欢这篇博客,期待你的一键三连。

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

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

相关文章

枚举对象序列化规则(将Java枚举转换为JSON字符串的步骤)

文章目录 引言I 案例分析1.1 接口签名计算1.2 请求对象1.3 枚举对象序列化II 在JSON中以枚举的code值来表示枚举的实现方式2.1 自定义toString方法返回code引言 在Java中,每个对象都有一个toString方法,用于返回该对象的字符串表示。默认情况下,Enum类的toString方法返回的…

C语言笔记30 •单链表经典算法OJ题-2.移除链表元素•

移除链表元素 1.问题 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 2.代码实现&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> #include <stdlib.h&g…

【RHCE】转发服务器实验

1.在本地主机上操作 2.在客户端操作设置主机的IP地址为dns 3.测试,客户机是否能ping通

特征及特征选择

1、特征&#xff08;Feature&#xff09;是什么&#xff1f; 特征是数据集中的一个可量化的属性或变量&#xff0c;用于描述数据点的特性。 特征可以是连续的数值&#xff0c;如身高、体重等&#xff0c;也可以是离散的类别&#xff0c;如性别、种族等。 常见的特征有边缘、角、…

Mosh|初学者 SQL 教程

sql文件链接&#xff1a;链接: https://pan.baidu.com/s/1okjsgssdxMkfKf8FEos7DA?pwdf9a9 提取码: f9a9 在mysql workbench 导入 create_databases.sql 文件&#xff0c;下面是运行成功的界面 快捷方式&#xff1a;全部运行可以同时按下controlcommandenter &#xff0c;或者…

Linux学习之网络配置问题

Linux学习——那些我们网络配置遇到过的问题&#xff1f;ping不通百度&#xff1f;XShell连接不上&#xff1f;&#xff08;超详细&#xff09; &#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感…

详细谈谈负载均衡的startupProbe探针、livenessProbe探针、readnessProbe探针如何使用以及使用差异化

文章目录 startupProbe探针startupProbe说明示例配置参数解释 使用场景说明实例——要求&#xff1a; 容器在8秒内完成启动&#xff0c;否则杀死对应容器工作流程说明timeoutSeconds: 和 periodSeconds: 参数顺序说明 livenessProbe探针livenessProbe说明示例配置参数解释 使用…

生产者消费者模型和线程同步问题

文章目录 线程同步概念生产者消费者模型条件变量使用条件变量唤醒条件变量 阻塞队列 线程同步概念 互斥能保证安全,但是仅有安全不够,同步可以更高效的使用资源 生产者消费者模型 下面就基于生产者消费者来深入线程同步等概念: 如何理解生产消费者模型: 以函数调用为例: 两…

LNMP搭建Discuz和Wordpress

1、LNMP L:linux操作系统 N&#xff1a;nginx展示前端页面web服务 M&#xff1a;mysql数据库&#xff0c;保存用户和密码&#xff0c;以及论坛相关的内容 P&#xff1a;php动态请求转发的中间件 数据库的作用&#xff1a; 登录时验证用户名和密码 创建用户和密码 发布和…

存储产品选型策略 OSS生命周期管理与运维

最近在看阿里云的 云存储通关实践认证训练营这个课程还是不错的。 存储产品选型策略、对象存储OSS入门、基于对象存储OSS快速搭建网盘、 如何做好权限控制、如何做好数据安全、如何做好数据管理、涉及对象存储OSS的权限控制、使用OSS完成静态网站托管、对OSS中存储的数据进行分…

ubuntu使用kubeadm搭建k8s集群

一、卸载k8s kubeadm reset -f modprobe -r ipip lsmod rm -rf ~/.kube/ rm -rf /etc/kubernetes/ rm -rf /etc/systemd/system/kubelet.service.d rm -rf /etc/systemd/system/kubelet.service rm -rf /usr/bin/kube* rm -rf /etc/cni rm -rf /opt/cni rm -rf /var/lib/etcd …

压缩感知2——算法模型

采集原理 其中Y就是压缩后的信号表示(M维)&#xff0c;Φ表示采集的测量矩阵&#xff0c;可以是一个随机矩阵&#xff0c;X代表原始的数字信号&#xff08;N维&#xff09;。 常见的测量矩阵——随机高斯矩阵 随机伯努利矩阵 稀疏随机矩阵等&#xff0c;矩阵需要满足与信号的稀…

57、基于概率神经网络(PNN)的分类(matlab)

1、基于概率神经网络(PNN)的分类简介 PNN&#xff08;Probabilistic Neural Network&#xff0c;概率神经网络&#xff09;是一种基于概率论的神经网络模型&#xff0c;主要用于解决分类问题。PNN最早由马科夫斯基和马西金在1993年提出&#xff0c;是一种非常有效的分类算法。…

OpenCV MEI相机模型(全向模型)

文章目录 一、简介二、实现代码三、实现效果参考文献一、简介 对于针孔相机模型,由于硬件上的限制(如进光量等),他的视野夹角往往有效区域只有140度左右,因此就有研究人员为每个针孔相机前面再添加一个镜片,如下所示: 通过折射的方式增加了相机成像的视野,虽然仍然达不…

精讲:java之多维数组的使用

一、多维数组简介 1.为什么需要二维数组 我们看下面这个例子&#xff1f;“ 某公司2022年全年各个月份的销售额进行登记。按月份存储&#xff0c;可以使用一维数组。如果改写为按季度为单位存储怎么办呢&#xff1f; 或许现在学习了一维数组的你只能申请四个一维数组去存储每…

修改服务器挂载目录

由于我们的项目通常需要挂载一个大容量的数据盘来存储文件数据&#xff0c;所以我们每台服务器都需要一个默认的挂载目录来存放这些数据&#xff0c;但是由于我们的误操作&#xff0c;导致挂载目录名字建错了&#xff0c;这时候后端就读不到挂载目录了&#xff0c;那我们我们的…

公司内部配置GitLab,通过SSH密钥来实现免密clone、push等操作

公司内部配置GitLab&#xff0c;通过SSH密钥来实现免密clone、push等操作。以下是配置SSH密钥以实现免密更新的步骤&#xff1a; 1.生成SSH密钥 在本地计算机上打开终端或命令提示符。输入以下命令以生成一个新的SSH密钥&#xff1a;ssh-keygen -t rsa -b 4096 -C "your…

AGE Cypher 查询格式

使用 ag_catalog 中的名为 cypher 的函数构建 Cypher 查询&#xff0c;该函数返回 Postgres 的记录集合。 Cypher() Cypher() 函数执行作为参数传递的 Cypher 查询。 语法&#xff1a;cypher(graph_name, query_string, parameters) 返回&#xff1a; A SETOF records 参…

高铁站客运枢纽IPTV电视系统-盐城高铁站西广场IP电视系统应用浅析

高铁站客运枢纽IPTV电视系统-盐城高铁站西广场IP电视系统应用浅析 由北京海特伟业科技有限公司任洪卓于2024年7月9日发布 随着科技的飞速发展&#xff0c;特别是“互联网”战略的深入推进&#xff0c;高铁站客运枢纽的信息化建设成为提升服务质量、增强乘客体验的重要手段。盐…

FTP与TFTP

1、TFTP&#xff08;简单文件传输协议&#xff09; TFTP是TCP/IP协议族中一个用来在客户机与服务器之间进行简单文件传输的协议&#xff0c;提供不复杂、开销不大的文件传输服务。 基于UDP协议 端口号&#xff1a;69 特点&#xff1a;简单、轻量级、易于实现 传输过程&…