指针详讲(一阶指针和二阶指针等指针各种用法详解)

首先,大家好,我是大家的超级无敌帅的代码老师。

给大家分享一段话:

“登顶之路注定坎坷;

哈哈哈哈,不管是学习还是生活,咱们得去看看山顶的风景啊!”

话不多说,咱们开干!

一:指针是什么?

 首先,指针是内存单元的最小编号,也就是地址。

大家看这个图,我们说,程序运行的时候也会用到内存,内存是怎么编排的呢?怎么编号的呢?我们等下再说。

我们首先应该知道我们通常所说的指针其实是指针变量,那么什么是指针变量呢?指针变量是用来存放地址的变量,例如:int *pa=&a;这句话的意思其实是,我用一个int 类型的变量将a的地址存放起来,欧克,那么这个a是int用int*加变量名要是是char float double又该怎么办呢?

 很简单吗!什么类型的就用什么类型的来存放吗?不然你看char类型就用char类型的来存放,以此类推。

了解了指针变量以后,我们再来讲一讲如何理解指针呢?

首先,我们假设有一台机器这台机器可能是32位也可能是64位,那我们这里就拿32位来举个例子,

 那么32位机器我们就让它有32个地址线,如果用2进制表示的话也就是2的32个格子,那么每一个格子就可以进行编号,2进制的话是0,1表示,那么第一个格子我们就给他编号为000000000000000000000000000000000共32个0,第2个格子编为000000000000000000000000000000001,那么一次类推,是不是每一个地址都能进行编号,那么此时我们把地址在c语言中叫做指针,很好,那我们已经知道什么叫指针呢,那一个指针变量的大小在32位机器上是多少呢?首先我们我要知道8个bit位等于一个字节,而一个KB=1024个byte(字节),一个MB=1024个kb,一个GB=1024个MB,往上还有TB等等,那我们了解基本的换算,我们来看首先我们有2的32次方个编号,也就是2的32次方个bit位 ,用2的32次方个bit除上1024一直除直到单位换算成字节为止,然后我们会发现,其实是四个字节,以此类推,在64位的地址上,不就是8个字节吗。(一格子占一字节)。

那么先跟大家讲一下指针的基本用法

看char*pa=&h的意思是把h的地址存起来,*pa的意思是通过pa访问h的

地址,此时h的值被改为0,这个 *是解引用操作符,是访问地址的,欧克

那我们来讲一下指针类型:

首先我们想一想指针既然是在32位机器上,的变量永远是四个字节,那么指针的类型char啊int啊等等还有什么意义呢反正大家都四个字节,我就不是没有意义吗?其实不是的。我们来看

 我们首先调试起来监视,我这里看的是b的地址,我给他设置成11223344,只不过在这种机器上地址是倒着存放的,也就是44 33 22 11.

这时我们让它将*pa=0走完

 你看这里地址已经全部变成了0;这是int类型其中地址两个数字是一个字节,也就是说它*pa的时候访问了四个字节。

那我们在来试试char类型

 大家看,我用char *pc来接收的时候,*pc这时候只改变了一个00,那么通过这个我们可以说,不同类型的指针访问字节是不同的。

大家再来看这两张图

 

 我们来看,我们分别打印了char int 存放的地址,还有char指针int指针加1出来的地址,此时我们会发现char int 存放的地址是同一个,所以打印一样但是,char指针加1地址加1,int指针加1地址却加4,由此我们得到指针类型的结论:
1,不同指针类型一次访问的字节不同 如 int 访问四个字节 char访问一个字节。

2,指针类型决定了指针的步长,如int+1跳过四个字节,char+1跳过一个字节。

接下来,我们讲野指针。

什么叫野指针呢?指向位置不可知的指针就叫野指针

最常见的成因,指针未初始化。

大家看,我这里int*p没有给它赋值,所以代码直接运行错误,出不来。

那我们如何来避免野指针呢

很简单吗,给指针初始化不就行了

 这里我用了两种初始化的方法:

1,int*p有明确的存地址对象的时候,比如这里的int*p=&a;

2.那如果没有明确的对象呢,我不知道该放什么,很简单这里用NULL,这是空指针的意思,是专门初始化指针的用法,但是注意了NULL是不能用*解引用操作符的,不然代码会崩掉。

接下来我在给大家讲一下避免野指针的东东:

1,初始化指针;

2,指针若是指向空间释放(不能用了),及时置空指针;

3,使用前判断指针的有效性,空指针NULL不用;

4,小心指针越界;

5,避免返回局部变量的地址。例如:int main(){int a=10;return &a;}

接下来,我们讲一下指针的运算

一:指针加减整数

我们拿这个代码举个例子

很简单啊,首先我们定义了一个#define 标识符常量N-VALUES=5;然后vp放的&values[0]下标为0的地址,把它放到for循环让他循环呗。只不过这个循环执行的语句*vp++;是什么意思呢?首先这个*操作符的优先级是低于++,那这里是后置++,先使用,再++先使用其实就是*vp=0;再vp++嘛,是不是,就相等于*vp++=0;等于*vp=0;vp++;就这样嘛。

同理如果我把*vp++改成*vp--;你会做吗?想一下。

接下来,我给大家讲一下指针减指针

二指针减指针:

首先,我给大家讲一个结论:

指针减指针的绝对值等于两个指针的元素个数;

而使用这个的前提条件是两个指针指向同一个空间。

来,我给大家举个例子

 前面的指针的实质是什么?大声的告诉我?是地址嘛,那我这里&arr[9]-&arr[0]当然算指针减指针,有人问了,为什么arr[10]十个元素为什么是&arr[9]-&arr[0]呢,很简单,数组下标是不是从零开始,减个一就ok了。你看看,10个元素减一个元素是不是等于9。

ok,我们讲下一个

指针的关系运算,上图

 来,直接上结论:

允许指向数组的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但不允许指向数组的指针与指向数组首元素的前面指针内存位置进行比较,ok,来看这道题。

你看,这个for循环的调整部分,也是表达式3是不是什么都没有,那你说,它要循环几次?看*--vp,前置--,先减减在使用,是不是vp=vp-1;*vp=0;他从指向数组第五个元素一直循环指向数组第一个元素的时候,你说,他还循不循环?当然不了,你看for里的vp>&values[0],我说了,它指向第一个元素的前面时候还循不循环,不循环嘛,结论吗?记住就行了。

🆗,总算讲完了一阶指针,来,上2阶及多阶指针。

 直接来看,我们想首先我们用一个int*p=&a;这句话的意思是我拿一个int 类型的p存放a的地址,那么要不要占用地址呢?当然要了,那么我们可不可以存放p的地址呢?当然可以,那 p的类型是什么呢?我们看我们存放a的地址用的是int类型 加上*再加上这个变量名p,那p的类型是不是int *呢?类型嘛加变量名是不是?那这个int* *ppa=&p其实就是2阶指针呢?同理,三阶,四阶,100阶,不久OK了。

今天就讲到这吧。

诸君,山顶见!

  • 23
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值