前言:
在学习指针与一维数组之间的关系前,我们先了解数组在栈区空间的存储方式(注意:类malloc开辟出来的空间不在栈区)。
我们先通过图来基本认识下一维数组,下面再做解释分析。
一维数组:
一维数组的存储
#include <stdio.h>
int main()
{
int arr[8];
int i;
for(i=0;i<8;i++)
{
printf("&arr[%d]=%p\n",i,&arr[i]);
}
}
通过代码:我们可以看到元素arr[i+1]的地址等于arr[i]的地址+sizeof(int)
这说明一维数组中的元素在栈区空间中是顺序存储的。
通过指针访问数组元素:
首先,需要定义一个指针,还需要一个数组。
其次,我们想将数组中的元素通过指针的形式访问出来,怎么访问呢?
①:通过访问元素地址
②:通过赋值
那我们就来看看这两种方式:
方式①:
#include <stdio.h>
int main()
{
int arr[8]={1,2,3,4,5,6,7,8};
int *p=NULL;
int i;
for(i=0;i<8;i++)
{
p=&arr[i];
printf("p=%d ",*p);
printf("arr[%d]=%d\n",i,arr[i]);
}
}
注意看:我要放大招了
赋值时,左右两边的类型需要一致:等号左边为*p(指针类型),所以等号右边应该是一个地址类型,故需要对数组元素取地址(&arr[i])
举例理解:这个相当于我们在玩游戏中的匹配机制,我们在匹配队友或者对手时,分配的队友和对手基本和我们都是同一段位的或者说是相同水准的。分配厉害的打不过,分配菜的打没意思,所以我们就想要那种旗鼓相当反复拉扯的感觉,这种赋值机制就类似游戏中的匹配机制。
结果分析:通过程序打印结果,我们可以看出指针打印出的结果就是数组中元素的结果,难道他们之间有着什么不可告人的秘密吗?
我们接着向下分析:
注意看程序中:打印*p的结果与arr[i]的结果相同,是不是就说明 *p==arr[i] 或者 p==arr???
假设p==arr:
验证:
我要变身了: 将 p=&arr[i] 换做 p=arr
竟然也能输出结果,但是这个结果怎么都是1?
我们前面说过赋值时,等号两边的类型需要相同,p=arr时也有结果,说明arr也是一个指针类型?
解释:这里的1就是元素arr[0]的值
知识点:数组arr就相当于数组元素arr[0],先记住,我们马上进行推理解释
方式②:
不知道大家有没有注意到,刚才我们在用指针打印数组元素时
竟然一样,天下有这么巧的事,我不信。难道 *p==arr[0]
假设:*p==arr[0] *(p+1)==arr[1] ? 还是arr[0]+1 那*p+1呢 ???
我们先看第一个(为了方便对比我们将数组修改为2,4,6(间隔为2)),后面在推广至*(p+i)或者*p+i,是大招哦!
我们看到:*p==arr[0] *(p+1)==arr[1]
这两不一样哦 *p+1==arr[0]+1
区别:*(p+1)与*p+1
*的优先级高于+,*p+1是指针的结果加一;*(p+1)是先将地址后移一个,再解引用,取地址(p+1)的结果
规律:*(p+1)==arr[1]=>*(arr+1) *p==arr==*(arr+0) 因为相等,所以两边同时去*=> p==arr
arr[0]==*p arr==*p 由上两式=>arr==arr[0]
验证:
由结果我们可以看出:p指向的地址是arr的地址,arr的地址和arr[0]的地址相同,由此可以确定arr就是数组首元素arr[0]的地址
推导至arr[i]又是大招:
#include <stdio.h>
int main()
{
int arr[8]={2,4,6,8,10,12,14,16};
int *p=NULL;
int i;
for(i=0;i<8;i++)
{
p=arr;
printf("*p+%d=%d ",i,*p+i);
printf("*(p+%d)=%d ",i,*(p+i));
printf("arr[%d]=%d ",i,arr[i]);
printf("*(arr+%d)=%d\n",i,*(arr+i));
}
}
结果分析:
- *p+i的结果是:*p的值(arr或者arr[0])+ i 的结果;
- arr[i]是通过数组访问元素的结果;
- 是*(p+i)是通过指针p访问元素的结果;
- *(arr+i)是我们通过结果,找出数组与指针之间关系的结果
通过上述的例子和实验结果分析,我们基本上已经了解数组与指针之间的关系了,如何通过指针访问数组元素,这将为我们后续学习二维数组与指针的关系与访问起着至关重要的作用。
总结:
一维数组中首元素地址和数组变量名地址相同;即在上述问题 arr==arr[0];
但是意义并非完全相同arr是整个数组arr[8]的首地址,而arr[0]只是数组首元素的地址,他们两在结果上是相同的,所以通过他们访问的数据结果也是相同的。