指针
指针作为C语言的核心部分,相比较其他的内容相对比较难懂一下,应用的方式多样,变化较多,导致很多的同学非常苦恼,那么接下来,我将陪你来共同揭开指针的神秘面纱;
指针的含义
大家不要把指针想的太难,指针其实就是通过地址找到对应的变量的位置,然后我们可以对地址进行解引用来访问变量的内存,来获取值的一种间接方法;我们通常说指针指向哪里哪里,就是指针变量里面存的其他变量(或者常量)的地址;即 指针->地址->内存;
普通变量指针
首先,我们现来看看指针的构成以及表达形式,比如:int *p;这里我定义了一个指针,我们来看他的构成,p是指针变量,这跟我们平时定义的普通变量没啥区别,但是我在p的前面加了一个 * ,那他就不同了,这个 * 是指针的标志,代表p是一个指针变量,而前面的 int 是指针变量p 要指向的变量的类型;
例如:
#include<stdio.h>
int main()
{
int *p,i;//定义整形指针变量p,和普通变量i;
p=&i;//这里我把普通变量的地址放进指针变量p中去
}
如你所见,指针变量就是用来存地址的,存的是谁的地址,就指向谁,然后我就可以通过对p解引用来访问指向的内存,或许,我们平时也见过这样定义指针的:
#include<stdio.h>
int main()
{
int i;
int *p=&i;
}
或许你会有疑惑,*不直接引用吗,为啥*p存地址了,其实这里的*不是解引用的意思,这个语句是在定义指针变量,所以*自然就是指针变量的标志了,在定义的同时,指向一个变量,其实就是把定义和取地址,合并了起来,这两个代码是等同的;
那接下来我们开始了解通过指针访问变量地址,话不多说上代码:
如图:我将普通变量的地址放在了指针变量p中,此时指针变量p就是指向变量i,注意p中的是i的地址;然后我通过对指针解引用,就是在指针前面加一个*,来通过地址访问i的内存,也就是i的值;很明显打印的值就是i的值;同理,浮点型,字符型的变量都是可进行如上操作的;
数组指针
数值指针,其主体是指针,他就是个指针,不过是有点不同而已,这个指针指向的是数组的地址,在此之前我们需要了解数组的地址;
数组的地址;
我们通常说数组的地址是数组名,是数组的首元素地址,也确实是这样,但是也有几种不同的情况:
1.当我们使用sizeof+数组名的时候此时数组名代表的是整个数组的地址。
2.当对数组名进行取地址的时候是整个数组的地址。
那整个数组的地址与数组的地址有什么区别呢:
数组的地址vs整个数组的地址
我们来看一段代码:
1.(这里的+1是将地址向后移动一位)数组名的地址+1后,我们发现增加了4个字节也就是一个整形的大小,而此时确实是指向了数组内第二个元素的地址,步长是一个元素类型所占字节数,也就是指向了下一个元素;
2.我们看后面两行,对数组名取地址+1的地址增加了'\x14'(地址是用16进制表示的),转化为10进制就是4+1x16=20个字节,而20个字节正好是整个数组所占的大小;说明移动后超出了数组,也就造成了数组越界。
3.打印的第一行和打印的第3行的地址是相同的,说明数组名就是数组首元素的地址,而对数组取地址的这个地址也同样是数组首元素的地址:
结论:二者都是数组首元素的地址,不同的是,步长大小不同;
我们再回到数组指针上;
正文
普通指针打印数组元素
上代码:
这里我先把指针指向数组的首元素,通过循环就可以实现数组的打印啦;值得一提的是p=arr;p就大致等同数组名了,所以我可以通过第二种打印方式实现打印数组各元素;
数组指针打印数组元素
数组指针,是一个指针,但是他指向一个一维数组,如图(*p)必须括起来,我们可以把他看成是数组名,关键点是因为指向的是整个一维数组,所以应该取整个数组的地址,应该加上&,然后我们把(*p)当成是数组名来对数组元素进行打印。
到了这里大家估计差不多明白了,指针的用法,就是指向一片内存空间,然后我们可以进行对其访问。
字符指针
含义
字符指针就是指针指向了字符或者字符串,因为字符串可以看成是一个字符数组,所以字符串指针与数组指针大致可以类比;
字符指针打印字符串
这里我使用了三种打印字符串的方式,从结果上看,很明显打出来的字符串都是相同的,其实我们平时打印字符串都是找到字符串的首地址,然后以%s的格式从地址向后打印;而指针正好指向的字符串,指针变量里面储存的就是字符串的首元素地址(这个跟数组是一样的);然后我们就可以完成打印啦。
指针数组
含义
指针数组,主体是数组,不同的是里面存的是指针,是地址;
指针数组打印二维数组
值得注意的是指针数组的[]前面的*p是没有括号的,我们可以这样看,他是一个数组,数组名是p,数组元素个数是3,(3个地址),p的前面加上一个*,就是指针,那就是指针数组啦,
总结:1.指针数组的形如*p[n]的数组,而数组指针是指针指向的是数组,形如(*p)[n],里面存的不是数组首元素的地址,而是整个数组的地址。
2.二维数组的数组名代表的是一行的一维数组的整个地址,当我们用数组指针指向二维数组时,就直接取二维数组的数组名就好啦。
本篇的指针的基本内容,就到这里,如果大家有什么问题,可以私聊,希望可以帮助大家进一步了解相关的内容。