- 指针和引用的区别
- 0、前言
- 1、指针、指针变量和引用
- 2、指针变量和引用变量的定义
- 3、引用的用途
- 4、引用和指针的区别
- 5、引用的底层原理
- 6、代码示例
- 6.1、示例程序1
- 6.2、示例程序2
最近学习严老师的数据结构,发现很多函数声明时都会使用到引用,首先呢,我们要说的是,“引用”是C++中的概念,因为我没接触过C++,所以只能简单地看来看两者的区别。
1、指针、指针变量和引用
首先,我们先来看看指针、指针变量和引用的概念。
指针:即内存地址。
指针变量:存放内存地址的变量,即指针变量的值为指针。
引用:某块内存的“别名”,给一个已经存在的变量起一个“别名”。
注意:
- 不同类型的指针变量所占用存储空间是相同的,32位机用4字节存储地址,因此,32位的指针变量所占空间为4字节;64位则为8字节。
- 引用不是新定义了一个变量,而是给变量取“别名”,因此,引用变量和引用的变量共用一块内存空间,编译器并不会为引用变量开辟新的内存空间。
2、指针变量和引用变量的定义
指针变量的定义:
int num = 18;
int* p = # //指针变量p的值就是num的内存地址
引用变量的定义:
//引用是C++中的概念!!!
int num = 18;
int &r = num; //引用变量r就相当于num的“别名”
注意:引用类型必须和引用实体是同种类型的,即变量是int型,则引用变量也必须是int型。
这一点倒是和指针很相似,关于指针类型和变量类型不兼容的问题,可以看《C语言_地址与指针类型不兼容造成的影响》)。
3、引用的用途
引用的主要用途:修饰函数的形参和返回值。
在C++中,函数的参数和返回值的传递方式有三种,分别为值传递、指针传递和引用传递。其中,引用具有指针的效率,又具有变量使用的方便性和直观性。
实际上引用可以做的事,指针都可以做,那为何还需要“引用”呢?
引用体现了最小特权原则,即给予程序元素完成其功能的最小权限,指针能够毫无约束的 *** 作内存中的任何东西,功能很强大,但也很危险。
4、引用和指针的区别
上面说了,引用可以做的事,指针都可以做,但是两者还是存在一定区别的。
- 初始化:引用在定义时必须初始化;指针则没有要求(尽量初始化,防止野指针)。
- 引用在初始化引用一个实体后,就不能再引用其它实体;而指针可以在任意时候指向一个同类型实体。
- 没有NULL引用,但是有NULL指针(空指针)。
- 占用空间不同:使用sizeof()函数,引用结果为引用类型的大小;指针始终是地址空间的大小,即32位机4字节,64位机8字节。
- 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小。
- 有多级指针,但没有多级引用。
- 访问实体的方式不同,指针需要显式解引用,引用编译器帮我们处理。
- 引用比指针使用起来相对安全(只是相对,不是绝对)。
5、引用的底层原理
引用一般都是通过指针来实现的,只不过编译器帮我们完成了转换。
我没学过汇编语言,但是我咨询了我的舍友大佬,他们通过编译器调试观察反汇编语言发现,引用和指针的反汇编语言是一样的,就是编译器帮我们完成了转换。
底层实现:引用通过指针实现,定义一个引用类型的变量相当于定义于一个指针类型的变量。
注意,引用是”别名“,不是指针,并没有发生拷贝,我们可以认为“引用”是“简单版的指针”。
6、代码示例 6.1、示例程序1
#include "stdio.h"
void modifyNumByPoint(int *p);
void modifyNumByReference(int &r);
int main() {
int num01 = 18;
int *p = &num01;
printf("num01 = %d\n", num01);
modifyNumByPoint(p);
printf("modifyNumByPoint--num01 = %d\n", num01);
printf("==========================\n");
int num02 = 20;
int &r = num02;
printf("num02 = %d\n", num02);
modifyNumByReference(r);
printf("modifyNumByReference--num02 = %d\n", num02);
}
void modifyNumByPoint(int *p) {
(*p)++;
}
void modifyNumByReference(int &r) {
r++;
}
结果:
num01 = 18
modifyNumByPoint--num01 = 19
==========================
num02 = 20
modifyNumByReference--num02 = 21
6.2、示例程序2
如果是在子函数内修改主函数的一级指针,一般在数据结构中用得比较多,如链表等等,则可如下定义:
//引用
void modifyByReference(int *&){
p = ……;
……
}
//指针
void modifyByPoint(int **p){
*p = ……;
……
}
注:如有错误,敬请指正!!!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)