C语言_指针和引用的区别

指针和引用的区别

0、前言

最近学习严老师的数据结构,发现很多函数声明时都会使用到引用,首先呢,我们要说的是,“引用”是C++中的概念,因为我没接触过C++,所以只能简单地看来看两者的区别。


1、指针、指针变量和引用

首先,我们先来看看指针、指针变量和引用的概念。

指针:即内存地址。

指针变量:存放内存地址的变量,即指针变量的值为指针。

引用:某块内存的“别名”,给一个已经存在的变量起一个“别名”。

注意:

  1. 不同类型的指针变量所占用存储空间是相同的,32位机用4字节存储地址,因此,32位的指针变量所占空间为4字节;64位则为8字节。
  2. 引用不是新定义了一个变量,而是给变量取“别名”,因此,引用变量和引用的变量共用一块内存空间,编译器并不会为引用变量开辟新的内存空间。

2、指针变量和引用变量的定义

指针变量的定义:

int num = 18;
int* p = #	//指针变量p的值就是num的内存地址

引用变量的定义:

//引用是C++中的概念!!!
int num = 18;
int &r = num;	//引用变量r就相当于num的“别名”

注意:引用类型必须和引用实体是同种类型的,即变量是int型,则引用变量也必须是int型。

这一点倒是和指针很相似,关于指针类型和变量类型不兼容的问题,可以看《C语言_地址与指针类型不兼容造成的影响》)。


3、引用的用途

引用的主要用途:修饰函数的形参和返回值。

在C++中,函数的参数和返回值的传递方式有三种,分别为值传递、指针传递和引用传递。其中,引用具有指针的效率,又具有变量使用的方便性和直观性。

实际上引用可以做的事,指针都可以做,那为何还需要“引用”呢?

引用体现了最小特权原则,即给予程序元素完成其功能的最小权限,指针能够毫无约束的操作内存中的任何东西,功能很强大,但也很危险。


4、引用和指针的区别

上面说了,引用可以做的事,指针都可以做,但是两者还是存在一定区别的。

  1. 初始化:引用在定义时必须初始化;指针则没有要求(尽量初始化,防止野指针)。
  2. 引用在初始化引用一个实体后,就不能再引用其它实体;而指针可以在任意时候指向一个同类型实体。
  3. 没有NULL引用,但是有NULL指针(空指针)。
  4. 占用空间不同:使用sizeof()函数,引用结果为引用类型的大小;指针始终是地址空间的大小,即32位机4字节,64位机8字节。
  5. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小。
  6. 有多级指针,但没有多级引用。
  7. 访问实体的方式不同,指针需要显式解引用,引用编译器帮我们处理。
  8. 引用比指针使用起来相对安全(只是相对,不是绝对)。

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 = ……;
    ……
}

注:如有错误,敬请指正!!!

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

窝在角落里学习

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

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

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

打赏作者

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

抵扣说明:

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

余额充值