首先我们需要明确一个优先级顺序:( ) > [ ] > *,所以:
int *p[n]:根据优先级,先看[ ],则p先与[ ]是一个数组,再结合*,这个数组的元素是指针类型,共n个元素,这是“指针的数组”,即指针数组。
int (*p)[n]:根据优先级,先看括号内,则p先与*结合所以它是一个指针,这个指针指向一个一维数组,数组长度为n,这是“数组的指针”,即数组指针;
1.指针数组
1.1指针数组的定义
指针数组是把多个指针,以数组的形式存储在内存中,数组中的每个元素都是一个地址,占有多个指针的存储空间。
1.2通过类比来认识指针数组
整形数组是用来存放整形的数组
int arr[5]={1,2,3,4,5};
字符数组是用来存放字符的数组
char arr[5]={'a','b','c','d','e'};
那么指针数组自然就是用来存放指针(地址)的数组了
int * arr[5];
1.3如何对指针数组进行赋初始值
int *arr1[]={"err","right","seek"}
上述代码就是通过将字符串常量的地址存入arr1这个数组中,这个数组的每一个元素是一个指针,分别指向这三个字符串常量的首地址
1.4指针数组的访问
![](https://i-blog.csdnimg.cn/blog_migrate/ee9cf4b2dc65c3af5b214240b36aae96.png)
int arr1[2] = { 1,2 };
int* arr2[2] = { arr1,arr1 + 1 };
printf("%p %p\n", arr1, arr2[0]);//两者都是arr1数组首元素的地址
printf("%p %p\n", arr1 + 1, arr2[1]);//两者都是arr1数组第二个元素的地址而且距离是四个字节
printf("%d %d\n", arr1[0], *arr2[0]);//对arr1首元素的地址进行解引用得到arr1的首元素
printf("%d %d\n", arr1[1], *arr2[1]);
}
事实上我们通过上面的代码不难看出指针数组只是装着指针(地址)的数组,通过对其解引用我们能够找到原来的变量
1.5指针数组与二维数组
事实上我们延续上述指针数组的访问方式不难发现,指针数组可以通过记录多个数组地址的方式来起到一种模拟二维数组的作用。
![](https://i-blog.csdnimg.cn/blog_migrate/cdf6650e09a671c71e469e4d6a39bac0.png)
int arr1[2] = { 1,2 };
int arr2[2] = { 3,4 };
int* arr3[2] = { arr1,arr2 };
printf("%p %p\n", arr1, arr2);
printf("%p %p\n", *arr3 , *(arr3+1));
printf("%d %d\n", *(*arr3), *((*arr3) + 1));
printf("%d %d\n", *(*(arr3+1)), *((*(arr3+1)) + 1));
不难观察出此处可以用[]来替代解引用的操作,p[n]=*(p+n)。大家可以自行尝试加深理解。
2.数组指针
2.1数组指针的定义
数组指针是一个指针变量,占有内存中一个指针大小(32位机器下时是四个字节,64位机器上为八个字节);数组指针即指向数组的指针,如:int(*arr)[3];含义是一个指向存放3个整形的数组的指针。
2.2数组名和&数组名
数组名:数组首元素的低地址。
&数组名:数组的地址。
两者虽然数值一样但是,所代表的的意义则是完全不同
对于整形数组来说,数组名+1指的是向后移动四个字节的第二个元素的地址。
但是对于&数组名来说,&数组名+1指的是移动该数组所占字节数大小的地址。
int arr[]={1,2,3};
printf("%p %p %p %p",arr,&arr,arr+1,&arr+1);
![](https://i-blog.csdnimg.cn/blog_migrate/e49b8c12e4d97d60591d089cb57c1267.png)
2.3如何对数组指针进行赋初始值
只有数组的地址才需要数组数组指针来来接收。
int arr[]={1,2};
int (*p)arr[2]=&arr;
2.4数组指针的访问
事实上我们不常用数组指针来接收一维数组的地址,直接用一级指针即可
int arr[] = { 1,2 };
int(*p)[2] = &arr;
int i =0 ;
for (i = 0;i < 2;i++)
{
printf("%d ", (*p)[i]);
}
2.5数组指针和二维数组
但是数组指针可以很好的接收二维数组并引用,因为此时数组名+1即是移动一行的元素。
int arr[][3] ={{1,2,3},{4,5,6}};
int(*p)[3] = &arr;
int i = 0;
for (i = 0; i < 2; i++)
{
int j = 0;
for (j = 0; j < 3; j++)
{
printf("%d ", (*(p + i))[j]);
}
printf("\n");
}
![](https://i-blog.csdnimg.cn/blog_migrate/4228be13a17e382d49a0122c2decdb8c.png)
3.总结
“数组指针”和“指针数组”,其本质只要看最后的后缀
数组指针:是一个指针,指向数组的指针。
指针数组:是一个数组,装着指针的数组。