1.指针与一维数组的联系
我们知道:(1)指针变量是用来存放别人地址的变量
(2)c语言中,数组的数组名或者数组第一个元素的地址就是数组的首地址
int *p;
p=arr=&arr[0]
根据这两点,我们是否可以定义一个指针变量来存放数组的首地址?看下图:

很显然,我们可以通过指针变量来存放数组首地址并成功访问出对应元素。
那么我们如何通过指针访问出下一个元素也就是2或者3呢?可以通过指针偏移的方式来访问下一个元素(因为数组的内存是连续的),因为我们知道指针指向的就是地址,也就是进行地址偏移。看下图:

*p指向的是地址,而*p+1你可能疑惑是内存地址这个16进制数加1?
并不是,底层逻辑是这样的:int类型是4个字节,而这里定义的arr数组是int型,因此数组的每个元素都是int型占4个字节,也就是16位,而每+1就是指针偏移一位跨度就是四个字节,看下图:

这里可以看到,元素1、元素2、元素3的地址分别是FE0C、FE10、FE14,是连续的,每隔一位差4,对应一个int(4个字节)的大小。因此就解释了上面可以通过指针偏移的方式来访问数组中下一位元素,因为数组元素内存是连续的,每偏移一位,跨度(增量)都是4个字节。
但是,上面这种访问方式太过粗糙了,要是数组中有n个元素,拿岂不是要*p+n到天荒地老?
带着这个问题往下看:我们是否可以通过循环的方式来解决这个问题?

从这个例子看到可以利用循环结合指针将数组中的元素遍历出来。这里的i就可以理解为数组每个元素的下标,把下标当作每次指针偏移的跨度(增量)。下面这个图中的写法得到的结果也是一致的,因此等价。

这里再紧接着引出一个问题,在做一个同样的循环,是否可以再一次循环遍历出数组的元素?

可以到,虽然遍历出了相同的元素,但是内存地址变了,根据变量四要素(变量名、变量值、变量数据类型、变量内存地址)我们可以知道,他并不是同一个东西。看下面这个图更加直观:

这个结果就是做一次同样的循环并不能访问出对应的元素了。也就对应了上面内存地址不同虽然得到同一个结果,但并不是同一个元素。
那么造成这个结果的原因是什么?怎么解决?
原因就是上一轮循环的指针经过偏移最终停到了下标2也就是对应元素3的地址上,再进行一次同样的循环,那么他就会从元素3的地址继续向后偏移,但是我们这个数组的元素只有1,2,3,就导致它后面并没有地址和对应的元素进行访问。
解决方法很简单,也就是进行一次指针复位

这里p=arr就是做的指针复位,也就是指针初始化。
总结:(1)数组名=数组首地址=数组的第一个元素的地址;也就是arr=&arr[0];再结合指针
int *p;p=arr=&arr[0];
(2)结合指针在进行数组遍历时:下面这几种写法写法也是等价的:

(3)值得一提的是下面这两种写法编译是错的:指针常量不允许进行++操作改变
指针常量,它的内存空间是已经定了的,不能进行改变,就比如下面这个arr数组,他就是指针常量,内存地址不能进行改变,只能通过内存的地址取值;指针变量,开辟了一个新的内存空间(他有自己的内存的地址),用于存放别人的内存地址,它就像一个火车站,空间是固定的,但是里面的乘客(别人的内存地址)是流动的不固定的,也就是可以改变的
