C与指针的神秘面纱
小编今天来水一篇文章,这个是小编很早之前就写了的,我们来讲解c与指针:
要说c语言中最具特色的东西,莫过于是指针了,今天,我们就来谈一谈指针,这个神秘但又如此吸引人的东西。
首先,我们来探讨一下为什么需要引进指针,这不得不提到一个老生长谈的问题了,那就是俩个数的交换问题了:
交换a b俩个数的值:
那么这样子就实现了a b俩数的交换了嘛,答案是否定的,那么这是为什么呢,这就不得不讲一下c语言中函数的传参了,对于这种普通变量,c语言在传参时,只不过是将实参拷贝一份复制给形参,所有此ab并非彼ab,所有并未改变main函数中ab的值,那我们应该怎么去解决这个问题呢,当然,其中最简单的方法,无疑就是直接把ab由局部变量直接提升为全局变量,这样子,无论是哪个ab,都是同一个了,但这样子做必然也有弊端,那就是全局变量比较危险,容易不小心被篡改,所有,我们走另一条路,那就是指针。
何谓之指针,其实指针不过也就一种变量来着,不过相比于普通的变量类型,Int float之类的,指针变量的解析方式不大一样,指针的一种专门用来指向地址的变量,而普通变量的访问方式就是通过地址,所有,指针提供了一种数据的间接访问方式,那么回归主题,我们应当怎么处理ab俩数的交换问题呢,且听我徐徐道来:
这上面涉及到俩个符号,即*和&,这里有俩个地方涉及到*,第一个毋庸置疑是用来定义指针变量的,那么第二个呢,是用于解引用,而&则是用于取地址的,因为指针变量中存储的是其他变量的地址,这样子才能够通过地址来进行访问嘛,那么这样子,也就可以引出另一个疑问点,如果指针没有初始化,理论上其里面也是有值的,那么其理论上也是可以指向一个地址的,这样子,也就可以引出我们的一个新的话题,野指针话题。
什么是野指针呢,其实本质也是指针来着,因为指针被定义了但确未进行初始化,所有指针变量所在的内存地址里面存着一个不确定的随机值,进而导致其解析时指向的地方是不确定的,这样子是非常的危险的,那我们应当如何取避免野指针问题呢,且听我分析分析:
野指针可能出现三种问题:
这一种便是指向了不可访问(操作系统不允许访问的敏感地址)的地址;第二种便是指向了一个可用的,但是没什么用的空间;第三种就是最危险的,指向我们程序正在用的一个变量的地址,这样子便会有可能篡改变量的数据,后果非常严重,那我们应该如何取避免野指针呢
这样子,我们便可有效的避免野指针带来的潜在危害。
那么通过上面的介绍,我相信各位已经对指针有了更加深刻的见解了,那么我们回归主题,来探讨一下,指针是如何让ab俩数的值实现调换的,让我们一步步解开指针神秘的面纱吧
首先,我们定义了一个swap函数,其没有返回值,传入的参数是俩个Int型的指针变量,所有我们传参赋值时,需要传的是地址,在看其内部,其实跟普通函数交换无不同,只不过里面的ab是指针变量来着,所有我们需要对其解引用,去间接操作目标地址中存储的那个变量,其实,从这里我们看出,其实ab俩个变量从始至终都未曾进来swap函数,我们之所以能操作地址,是因为变量在定义的时候,cpu就给该变量分配了一个确定的地址,是不会改变的,这样子,我们就解释清楚了为什么能通过访问地址空间去改变变量的值。
好啦,我们通过四页的篇章,终于是把指针讲清楚啦,当然,这还只是指针的冰山一角,下面我们来探讨一下另一个好玩的话题,我们我们指针既然能够指向普通类型的变量,int float之类的,我们c语言中可是有很多的数据类型的,没错,下面,我们来探讨一下数组指针,顾名思义,一个指向数组的指针,要想弄明白这个东西,我们至少得先知道一下数组的地址是怎么样的吧,毕竟指针解析就是用来指向地址的(doge.)
上面介绍了数组的内存中的空间是怎么样分配的
我们今天主要是来探讨几个东西
就是上面这几个符号,弄清楚了,我们就理解了数组的地址是什么样的了(doge.)
第一个,单一个a,其实这个就是数组名来着,也就是代表着数组首元素的首地址来着,这里应用了俩个首,首元素很容易理解,因为数组一般是有很多个元素的嘛,那首地址呢,其实因为一个字节就是一个地址,而Int型变量是有4个字节的,也就是有四个地址其实,所有要声明是首地址;我们继续讲,a[0]就不需要过多介绍了,就是数组的首元素嘛;&a,这个东西有一点特殊,我们知道,&是取地址符,而a其实是数组名来着,所有,&a其实是整个数组的地址,这个跟前面a俩个的地址类型是不一样的,一个只是首元素的首地址,而一个是整个数组的地址,我们在用指针去指向的时候,要特别注意类型匹配问题,这个问题我们后面再谈;好,那我们来聊最后一个&a[0],这个就比较清晰明了了,这个其实就是a[0]的地址来着,也就是跟a其实是同一个东西来着,总结:(doge.)
因为数组在分配空间时,是连在一起的,所有我们用指针去指向数组时,仅仅只需要指向其首元素的首地址即可,p=a;那么*(p+3)代表着什么呢,其实就是a[3]来着,这里需要补充一下指针的一点特殊性,
其实指针解引用的时候加1并不是代表着地址加1
好啦,经过上面的学习,我们已经看清了数组跟指针之间的朦胧神秘的关系了,我们又揭开了一层指针的面纱(doge.)
既然指针跟数组有着这么密切的关系,c语言中有那么多的数据类型,结构体呢,是不是也有呢,其实是有的,那会在哪里使用呢,在函数传参时,指针,就是一个相当不错的选择,避免了需要复制那么一大堆数据给形参,增加了程序的运行时间,真的是一把利器来着,在聊这个之前,我们先开启一篇神奇的篇章,同时也是笔者写这一篇笔记的初衷,因为笔者深深的被其的神秘所震撼,也就是函数指针,我们来探讨探讨,
其实函数也跟数组一样,数组有数组名,而函数也有函数名,俩个都是存在内存中的,都有着自己专属的地址,既然有地址,那我们指针就能大展身手了,我们来看看函数指针:
先大概讲到这里,后面函数指针等小编下次再补齐啦,先下播啦,完结,撒花(doge.强制版)