C语言——指针那些事

关于c语言的指针,总是觉得不得其道。哪怕了解了基本的p存的是地址啊,*p存的是内容等等,在阅读其他人的代码时也总是因为指针看的云深雾绕,不知道作者在干什么。今天,想借这篇笔记,整理一下指针的思路,复习旧的,学习新的,尝试未知的。

首先,我们先对指针要有一个基本的认识。什么是指针?想必大家也同我一样,看过了大量的视频,但模模糊糊的,总是觉得,搞这个东西干嘛?我敲java就从来不用这个,我敲的可好了!

事实上,Java的底层就是C和C++。而指针,对应java中的JVM(垃圾回收机制)。那我们说,这又是什么东西,又给我讲一堆概念,有用的没用的竟耽误我学主线。
其实,这是个理解指针的好例子。因为,指针我们知道,他是存东西的地址,就好像你的宿舍房间号是312(p),而我们的行李家当这些东西都存在里面(*p)。

那么,什么是垃圾回收呢?你在大学寝室312,将会住四年,这四年结束呢,你的就该拍拍屁股走人了。但是呢,你的寝室,还要留给下一届新生们。你留下的,不要了的东西,就需要像打扫寝室一样清除掉,留给下一届新生放他们的东西。在Java里,这个过程是自动完成的,叫做JVM。而在C和C++中,没有这种自动机制,你就需要,在入住的时候做好登记(int * p),在毕业不用这个房间的时候( free(p))。

那有的同学说了,我不释放你能把握怎么样?这,就引发了一个问题:内存泄露。你这个房间,将永远无法再有其他人入住,而事实上,由于你也不再需要他,那在程序运行期间,这片内存,将成为一块空间被浪费掉。我们将这种行为放大、累积,到一定程度,你将无内存可用。

你说,啊指针好可怕,我不用了。事实上我们说,这个世界上的东西永远都是辩证的,指针也是这样的双刃剑。和Java相比,指针可以提高编程人员对内存的操控,这将是一种极大的权利,运用得当,也将极大优化程序的效率。(况且为了学习考试,咱不还得学嘛)

回归正题,我们通过几种写法,直击指针应用,直观理解。

指针

定义了一个指针类型 p ( point缩写)。

int* p;//注意正确写法int*,意为int类型指针变量名为P

对于p这个指针变量,我们有两种操作方式*p和&p。
* 表示指向,&表示取地址。不理解也没关系,我们往下看。

假如 *p 置为3,则代表p这个房间里,我存上了个东西3。

*p = 3;

取地址符&

&p,我们输出一下发现它是一串数字。事实上他是什么,他是这个指针的地址,也就是这个p存的位置,可以理解成宿舍建在中央大街7089号这个位置。

printf("%d",&p);//1222241760,随机产生此处为样例

有同学问了,唉?那个p呢,我啥也不干,把它输出是个啥呀?哎,是的,他也可以输出。

printf("%d",p);//1222242000,随机产生此处为样例

你说这又是啥呀,乱七八糟的,还和上边不一样。事实上,这个,就是我们放东西的地方,或者说是你的房间号312,更微观地讲,就是你从哪一个内存单元格开始放行李。

至此,我们已经接触了三个东西,总结一下:
p,指针变量,我的房间在哪里。
&p,指针变量地址,我的宿舍在哪里。
*p,内容。我宿舍放了什么东西。

有的同学说,好,运算符是吧,那我可就要套娃了,看我真不真实。

*&p,&*p,**P,&&p

强大的你可以自行思考片刻,这些写法对不对,各是什么含义。

我们还是将行李设成3,输出一下:

int *p = 3;
p  //1935288288
&p //1935288048
*&p//1935288288
&*p//1935288288
**P//报错
&&p//报错

对结果有所预料了?恭喜你,指针你已经理解一半了。
p,还是我们房间号,存东西的地址
*&p和&*p,其实他们两个和p是一个东西,区别是操作顺序的不同,即前者是对p先取地址再指向这个地址,后者是指向p看看里边有什么东西在出来瞄一眼房间号。
正常来说这两种写法毫无意义,没人脑袋有问题这么写的。

那我们说,**p和&&p怎么报错了呢?其实他们在某些情况下是正确的,我们来分析下:
**p,意为对p的内容再指一次。如果我们初始的值不设为3,而是一个地址的话。。。那么,我们第一步,指向p来获得p房间里这个存的地址,接下来,在通过再指一次,指向这个新地址的内容,如果这个新房间里存了个4,那将会输出4。

而对于&&p,我们理解一下,首先&p找到存p的这个地址,那么再&一次意思是什么呢?就是找到存p这个地址的这个变量的地址。如果这个变量存在,就可以取到,而没有,自然会报错。是不是挺顺的,没错你想的一点也不对!
&&这个符号,在编程语言里,不是叫且吗?就是我们做条件判断时候,两个条件同时成立的连接符号。事实上,&&p这个写法并不成立,事实上,前面说的是有道理的,不过并不是因为我们没有设置才没有,而是因为,这个地址数字,是一个虚拟的值,对数字取地址,自然是不成立的。(未完待续。。)

引用

我们可以用以下方式定义一个引用。

int& b =a;

引用,表示给a取别名,此时b和a等价。
引用的应用,在于解决函数传参多返回值的可读性问题。
我们往往用指针达成多值返回,但指针的可读性差,某些情况下会导致数星星。
所以引用的引入,使我们看起来更舒适自然。

引用传参

在这里插入图片描述

指针降级

在这里插入图片描述

注意
1.引用必须初始化
2.引用只能绑定一个对象(初次)
3.引用不可以赋值为常量。

指针,取地址,引用

至此,我们讨论一下他们三者的关系:
指针p:存储变量的地址
int* p=&a;表示定义一个指针变量p,p存储的是a的地址。
而对于*p:表示取地址,表示解引用,表示访问值。
int& b = a;表示定义一个引用变量b,其绑定的对象为a。

总之,从科学的角度,在定义时应写为int* p和int& b,而非int p和int &b。
p和
p不是一个东西,int* p也不等于*p,int& b和&b也不是一个东西。

解释清楚没?散会

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值