【指针数组 & 数组指针】
指针数组本质是数组,只不过这个数组里的元素都是指针元素。
数组指针本质是指针,这个指针指向数组。
看一个表达式是数组指针还是指针数组,关键在于核心通过优先级比较,最先跟谁结合。
-
指针数组
int *p[1]
通过优先级比较,上述表达式的核心p
会先合[]结合,因此上述表达式的本质应该是数组,其次加上*后,这个表达式可确定为指针数组,数组的元素都为指针,指向的都是int整型。
指针数组的使用细节:
void fun1(){
int i;
int *p[5]; //声明一个指针数组
int a[5]={1,2,3,4,5};
for(i=0;i<5;i++){
p[i] = &a[i]; //需要循环赋值初始化
//int *p[5]={1,2,3,4,5};是错误写法,数组p的元素都是指针(地址)
}
//数组名地址==第0个元素的地址
printf("%p-----%p\n",a,&a[0]);
//p的地址是这个指针数组的地址
printf("%p\n",p);
//p[0]的地址是指针数组中第0个元素(指针)存放的地址 p和p[0]不是一个地址 p和&p[0]应该是一样的
printf("p[0]地址:%p---%d\n",p[0],*(p[0]));
printf("p地址:%p---p[0]地址:%p\n",p,&(p[0]));
//通过p[0]和p[1]的地址可以验证,32位机器指针占4个字节
printf("p[1]地址:%p---%d\n",p[1],*(p[1]));
}
- 数组指针
int (*p)[10]; //int (*)[10] p -----> int (*)[10]为指针类型,p为指针变量
通过优先级比较,因为()的存在,上述表达式的核心p
会先合*结合,因此它本质是一个指针,指向一个int类型的数组。
数组指针细节:
void fun2(){
int (*p)[5];
int arr[5][5];
p = arr; //数组指针指向二位数组
//通过打印地址可以发现,p指向的是二位数组的第一行
printf("%p-----%p\n\n",p,arr[0]);
//arr[0][0]的地址同arr[0]地址,道理同一维数组一样
printf("%p-----%p\n\n",p,&arr[0][0]);
//通过打印地址可以发现,p后移指向的是第二行数组,并不是第一行的第二个元素
printf("%p-----%p\n\n",p+1,arr[1]);
//因此p[0]即第一行的首地址,此时再后移,则指向的就是第一行的第二个元素
printf("%p-----%p\n\n",p[0]+1,&arr[0][1]);
}
简单总结一下...
指针数组:首先它是一个数组,数组的元素都是指针,数组占多少个字节由数组本身的大小决定,每一个元素都是一个指针,在32 位系统下任何类型的指针永远是占4 个字节。它是“储存指针的数组”的简称。
数组指针:首先它是一个指针,它指向一个数组。在32 位系统下任何类型的指针永远是占4 个字节,至于它指向的数组占多少字节,不知道,具体要看数组大小。它是“指向数组的指针”的简称。
本文是个人总结,如果哪有问题、或者理解方法不对,还烦请大神帮忙指出来,十分感谢~~~