【1++的C++初阶】之C++入门篇2

👍作者主页:进击的1++
🤩 专栏链接:【1++的C++初阶】

一,引用

1.1 什么是引用

引用是给一个已经存在的变量取 ’别名‘ 。它两共用一块空间,例如:你的名字与你的小名,不论叫谁都指的是你。

1.2 引用的特性

1.引用在定义时必须初始化
2.一个变量可以有多个引用,就像你可以有多个小名或外号。
3.引用一旦引用一个实体,那么这个引用就不能在引用其他实体。

1.3 常引用

using  std::cout;
using std::endl;

int main()
{
	//a由const修饰变为常量,则a的引用也得为常量
	const int a = 1;
	const int& b = a;
	cout << a <<' ' << b << endl;
	//c为常量,则引用时需要用const修饰,不可修改
	const int& c = 2;

	//引用与引用实体的类型必须相同
	double d = 3.14;
	double& q = d;
	cout << d <<' '<< q << endl;
	return 0;
}

运行结果:
在这里插入图片描述

1.4 引用的应用场景

1.4.1 做参数

引用在做参数时对形参的操作实际上就是对实参的操作,这与我们传指针的作用是相同的。并且,虽然引用的操作与传地址是不同的,但是在汇编代码中,他们的实现基本是一样的。
在这里插入图片描述
在这里插入图片描述

通过观察汇编代码我们发现两函数的汇编是相同的,证实了我们上述的结论。

1.4.2 做返回值

引用在返回值中的应用要特别 注意,我们以下述代码为例:

int& Add(int a, int b)
{
	int c = a + b;
	//static int c = a + b;
	return c;
}
int main()
{
	//做参数
	int& ret = Add(1, 2);
	cout << ret << endl;
	return 0;
}

当Add函数运行时,编译器会为其开辟函数栈帧,当函数结束时,编译器会回收为其开辟的栈帧,我在前面的文章【函数栈帧(详解版)】中详细介绍过函数栈帧。而定义在函数中的变量c为其开辟的空间也在栈帧中,所以当函数结束时,c的空间也被回收(这里的回收指的是函数不再对这块空间有使用权,但是这块空间仍然存在。所以引用在做返回值时,引用的实体为c,当函数结束,c销毁,我们再次通过引用访问c时,就会造成内存越界访问。解决办法就是增长c的生命周期,可以定义为全局变量,也可以用static修饰

1.4.3 引用和指针的区别

在语法概念上,引用就是一个别名,没有独立的空间,与实体共用一块空间。

在底层实现上,引用和指针的实现是差不多的。
不同处:1.引用必须初始化,但是指针可以不用。2. 引用只能有一个实体,但是,指针能够指向相同类型的不同变量。3. 没有NULL引用,但是有NULL指针。4. 指针大小为4/8字节,但是引用的大小为实体类型大小。5.指针自加,即指针向后偏移一个类型的大小,但是引用自加为实体加1。6.有多级指针,但没有多级引用。7.引用比指针更安全。

二,内联函数

2.1 什么是内联函数

以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方将函数展开,这样做就没有了函数建立栈帧的开销,提高了效率。

以下代码为例:

#include<iostream>
using std::cout;
using std::endl;
inline int Add(int a, int b)
{
	return a + b;
}
int main()
{
	int ret = Add(1, 2);
	return 0;
}

无inline修饰:
在这里插入图片描述
有inline修饰
在这里插入图片描述

通过比较上述两张汇编代码图,我们可以得出结论就是,在有inline修饰后,就没有了函数调用call,而是直接直接用函数体替换函数。

2.2 内联函数的特性

1.内联说明只是向编译器发出的一个请求,编译器可以选择忽略这个请求。一般是函数规模较小,不是递归,并且频繁调用的函数采用inline修饰。
2.使用inline时,不建议声明与定义分离,因为inline被展开后,就没有函数地址了,就会链接错误。
3.内联函数可能会使目标文件变大。
在这里插入图片描述

内联与宏的区别就是,内联在Debug下可以调试,而宏不可以。解决了使用宏时的代码可读性差,可维护性差的缺点。

三,C++中的空指针

在C语言中我们认为NULL是空指针,但实际上NULL是一种宏
其代码如下:

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

我们可以看到,在C中,NULL是被定义为void*的常量,但是如果使用C++的编译器,NULL就是常量0。
因此,在C++11中引入了关键字nullptr,来表示空指针。并且sizeof(nullptr)在x86下大小为4,在x64下为8.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

进击的1++

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值