1.指针是什么
在学习之前,要先讲解一下地址的概念。就想每个家都有自己的门牌号一样。内存也给自己的内容取了名字,这个名字就是地址。那么问题来了,“名字”占多大内存呢?答案由你的电脑决定。那32位处理系统为例,32位处理系统就意味着32根电路来运算。每根线路传达的电信号只有0和1.所以32位处理系统就只能处理2^32个信号。这些信号在除以GB再除以MB……最终化成了4个字节,再分就小于0了。所以32位处理系统所划分的最小单位是4个字节。而这4个字节就是一个地址的大小。同理也可以算出64位处理系统最小单位是8个字节。指针存储的就是地址。
所以指针和地址的大小是固定的,32位平台是4个字节,64位平台是8个字节。
2.如何定义指针
如图所示,定义指针时,我们要有指针类型,如果我们定义的是一个int类型的变量,那么我们也要用一个int*类型的指针,这里的*代表着我定义的是一个指针 ,int代表着我指针里存放的是一个int类型的变量的地址。
3.指针的解引用
指针解引用的符号是 *
可以看出来,指针解引用后可以给a改值,这就是指针的解引用。
4.指针类型的意义
我们定义变量时要有变量类型来开辟多少空间 ,但是前面我们说到指针的大小是固定的,所以指针变量好像没什么大用处。但是指针变量存在就有意义,它主要有以下两点意义:
4.1 指针解引用跳过多少字节
从图中可以看出来,用int*来定义的指针变量+1后向后变动了4个字节(int类型的大小),而char*的指针+1只变动了一个字节(char类型的大小)。所以我们说指针类型决定了+1后变化多少字节。(-1同理)。
4.2指针赋值后改变多少字节
由图可以看出,指针类型还决定着指针赋值可以访问几个字节
5.野指针
野指针是一种危险的指针利用形式,书上说的野指针是指向随机地址(不可知,随机指定)的指针。我的理解是没有拴绳子的野狗。野狗会到处乱窜,咬人所以会危险。野指针解引用时就好比野狗一样,她在随机地址处改值,并且你还查不到,这就很危险。下面我会给出野指针的主要出现形式以及如何规避野指针
5.1野指针的主要出现形势
(1)没有初始化
(2)数组越界访问
数组只有十个元素,而你却让他循环了16次,这样数组越界访问了,产生的野指针就只能在内存里随便找空间赋值了。
(3)指针指向的空间释放掉
典型就是打开文件时,free掉之后没有置成NULL。或者函数出来时自动销毁空间,却传回指针。
5.2如何规避野指针
(1)指针初始化
(2)数组访问时多检查检查,不要越界
(3)及时置成NULL
(4)函数返回时要确定传回指针的不是已经释放的空间
6.指针运算
指针指向的是地址,所以指针-指针就是地址-地址得到的是两个指针之间的元素个数。
可以用这个方法模拟实现strlen函数
此外
C语言的语法标准规定:
允许指向数组元素的指针与指向数组最后一个元素后面的那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置的指针进行比较。
7.指针和数组
我们常说数组名是首元素的地址,它和指针有着密切联系,但两个不是一回事
我们把数组名和数组首元素的地址打印出来后发现,这两个地址完全一样。所以数组名就是首元素的地址。
那么既然数组名是地址,那么我就可以把它放在指针里,用指针来访问数组的元素。比如
p是首元素的地址,那么p+i就是第i个元素的地址,*(p+i)就是第i个元素,这样我就可以访问数组的每个元素了。
8.二级指针
既然指针是一个变量,那么它也有地址,我可以把他的地址用一个指针的形式来存起来,这个存放指针的指针就是二级指针。比如
二级指针的定义以及解引用和一级指针一样,只不过是加了一个*,这里就不啰嗦了。
当然二级指针也可以存起来,三级指针也可以存起来。(可以套娃)
9.数组指针和指针数组
从名字上可以看出数组指针是一个指针,指向的数组的地址,而指针数组是数组,数组的每个元素的是指针。那么如何来辨别他们两个呢?其实很简单,我们说只要是指针,那么他的名字就和“ * ”结合,只要是数组,他的名字就和“ [] ”结合。而“ [] ”的优先级要比“ * ”高。所以数组指针要用到()
比如
而指针数组是这样的
在这里说明一下,二维数组可以看成一维数组的数组,所以他的首元素是个数组。如果用int或其他类型的指针,那他指向的是第一个一维数组的首元素,如果用数组指针,只要元素个数和第一个一维数组相等,那他指向的是第一个一维数组。
10.函数指针
函数在内存中也会有空间来存放,所以他也可以用指针来接收。比如
看到这里,我所知道的指针的基础知识就讲完了,如果有补充或者不对的地方,欢迎指出来。