👍作者主页:进击的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.