1.什么是指针
指针类似于书的目录,主要就是为了寻址。
定义:
类型+ * +变量名 =指针
2.如何使用指针
int a=10,*p;
p=&a;
这里*p意思就是定义一个指针,但是未初始化。
p 代表的是地址。
*p 意思就是这个地址中存放的内容。
3.野指针和NULL
什么是野指针呢?
野指针指向一个已删除的对象或未申请访问受限内存区域的指针。
什么是空指针呢?
就是你定义了一个指针却没有指向任何地址。
例程(为空指针分配内存):
4.什么是数组指针
看后缀名是落在指针,也引出了其内容,数组指针就是一个指向数组的指针。
看图片,可以了解到在这里*p=a和*p=&a[0]都是代表着p是指向a数组的首地址。而p+i也就是等价于&a[i],也就是数组中元素的地址。
例程(通过指针打印数组中的元素):
5.什么是二维数组指针
就是一个指向了二维数组的指针。其实一个二维数组可以看成是由多个一维数组组成的。
数组名a是这个二维数组的首地址,也是a[0]的首地址即a[0][0]。
a+1是数组a[1]的首地址。即a[1][0]的地址。
注意:二维数组名a的增量是a[0]和a[1]数组长度为单位的。所以a+1就直接跳到了a[1]这个数组。
指针指向二维数组的操作:
int (*p)[3]=a;
解释:指针p指向包含3个int元素的一维数组,p指向的是二维数组a的首地址,所以可以明白p+1实际等于a+1。
*p+1是a[0][1]的地址。
*(p+1)是a[1][0]的地址。
*(p+1)+1是a[1][1]的地址。
个人理解总结:1.二维数组实际上也是一维数组,在上例中a[2][3]的二维数组中。a[0]和a[1]是二维数组的两个元素。
2. p是指向二维数组的首地址a,所以p=a。对于二维数组的角度来看,a[0]是二维数组的第一个元素。所以p是指向首地址得出p=&a[0]=a。
3.a[0][0]=a[0]=*p; a[0][1]=*(*p+1); a[1][0]=*(*(p+1)+1);
6.什么是字符串指针
指向字符串的指针。
定义:
char *p=”My dream is a coder”;
打印全部的值:
printf(“%s\n”,p);
打印单个字符:
printf(“%c\n”,*(p+1));
结果是 : y
7.什么是指针数组
应该与前面的数组指针进行区别,这个后缀名是落在数组。所以说指针数组就是一个数组里存的都是相同类型的指针。
如果我们不使用指针数组效果怎么样?
char arr[][]={“我是码农”,”我不是码农”,”我到底是不是码农”};
这种方式是按照定义二维数组的方式,会浪费空间。
如果我们使用指针数组效果怎么样?
char *p[3]={ “我是码农”,”我不是码农”,”我到底是不是码农”};
这种方式定义的是一个一维数组,里面存了三个字符串指针。
例程(打印指针数组):
就是和前面打印数组指针的套路是一样。
8.什么是指向指针的指针
指针存在的目得就是为了寻址。
举例:
张三通过地址去找王五玩。这是指针寻址。第一次张三去找王五,是通过别人寻找王五,那么张三通过地址先去找李四,再通过李四的地址去找王五玩。就是指向指针的指针。
例程(使用指向指针的指针打印数组):9.什么是指针的长度
指针长度是固定的。取决于你的电脑是多少位的,如果是32位的,那么指针长度是4。如果是64位的,那么指针长度是8。
10.为什么使用指针作为函数的参数
由于之前交换两个值,如果在自定义的函数中实现了值交换,但是参数只是值得话,并没有将交换的值返回到main函数中。所以为了使值交换后,在main函数中,可以显示出来。那么就需要使用指针来作为函数的参数。
例程(使用指针作为函数参数实现值交换):
注意:
指针作为参数时,把指针变量的内容(就是其指向的内存地址)做了拷贝;数组名作为参数时,把它等同于指针看待了。
11.指针函数
顾名思义,指针函数就是返回值为指针的函数。一般我的套路都是返回数组时使用指针来返回。
例程(使用指针作为返回值来截取字符串):
12.结构体指针
就是指向结构体的指针。
指针打印结构体中变量值的方式有两种:d->year和(*d).month。