数组指针和指针数组
由于[]的优先级高于*,指针存储内存地址,指针数组就是一个数组里面存储了10个指针,而数组指针则是一个指向了数组首地址的指针
数组指针可以看着是一个数组类型的指针如 int (*p2)[10] 可以看做是一个类型为整形数组(int (*)[10]
)的指针,指针变量为p2。
要弄清指针数组和数组指针的差别我们首先要弄清a与&a的区别, "&a"代表数组的起始地址a则代表首元素首地址 .
int main()
{
char a[5]={'A','B','C','D'};
char (*p1)[5] = &a;
char (*p2)[5] = a;
return 0;
}
对于上述代码中p1、p2都是指向一个由5个字符变量组成的数组,&a是整个数组的起始地址,a是数组首元素的首地址,虽然他们两的值相等,但意义确并不相同,第5行代码会产生warning initializing of char (*)[5]’ differs in levels of indirection from 'char *'的报错,这就是因为(*p2)[5] 与a的类型不同造成的。
#include<stdio.h>
int main()
{
int a[5]= {1,2,3,4,5};
int (*p3)[10] = &a;
int (*p4)[10] = a;
printf("sizeof(a)=%d\n",sizeof(a)) ;//a数组占用20个字节的内存空间 sizeof(a)=20
printf("a = %p\n",a); // 数组名代表首元素首地址 . 0x7ffec762ba20
printf("&a = %p\n",&a); // "&a"代表数组的起始地址 . 0x7ffec762ba20
printf("a+1 = %p\n",a+1); // +1代表加上一个整形变量的地址 0x7ffec762ba24
printf("&a+1 = %p\n",&a+1); // +1代表加上一整个数组的地址 . 0x7ffec762ba34
printf("&P3 = %p\n",&p3); //数组指针p3的地址 0x7ffec762ba10
printf("&P4 = %p\n",&p4); //数组指针p4的地址 0x7ffec762ba18
printf("P3 = %p\n",p3); //数组指针p3的值(存储了数组a的起始地址) 0x7ffec762ba20
printf("P4= %p\n",p4); //数组指针p4的值(存储了数组a的起始地址) 0x7ffec762ba20
}
那么如果我们将整型数组的元素增加到10个会出现什么情况呢,结果是一样的,&p3是数组指针p3的地址,p3则是指向整型数组的起始地址的指针,*p3则是整型数组首元素的起始地址,**p则是整型数组第一个元素的值。