- 概念
指针数组:指针的数组,表示一个数组,并且数组的每一个元素都是指针类型。int p0[5]; int *p1[5]; //指针数组 int (*p2)[5]; //数组指针
数组指针:数组的指针,表示一个指针,并且是指向数组的指针。
-
运算符优先级:
**()
>[]
>*
** -
对于
int p0[5]
来说,p0
先与[]
组合构成一个数组,数组名叫p0
,而int
修饰的是数组内的内容,即数组内的每个元素都是int
类型的,该数组包含5个指向int
整型的数据变量。
-
对于
int *p1[5]
而言,因为[]
的优先级大于*
,所以,p1
先和[]
结合构成数组,数组名为p1
,而此时int *
修饰的是数组内的内容,即该数组内的包含5个指向int
类型数据的指针,所以,是指针数组。 -
对于
int (*p2)[5]
而言,因为()
优先级大于[]
,所以,括号()
内的*
先和p2
组合构成一个指针的定义,指针变量名为p2
,而此时int
修饰的是数组内的每个元素。
也就是说,p2
是一个指针,指向了一个包含5个int
类型数据的数组首地址,所以,是数组指针,此时数组在这里是没有数组名的,是个匿名数组。
- 容易混淆的一些概念
- 一个整形
int a;
- 一个指向整形数的指针
int *a;
- 一个指向指针的指针,它指向的指针指向一个整形数
int **a;
- 一个有5个整形的数组
int a[5];
- 一个指向有5个指针的数组,该指针指向一个整形
int *a[5];
(指针数组) - 一个指向有5个整形数数组的指针
int (*a)[5];
(数组指针) - 一个指向函数的指针,该函数有一个整形参数并返回一个整形数
int (*a)(int);
- 一个有5个指针的数组,该指针指向一个函数,该函数有一个整形参数并返回一个整形数
int (*a[5])(int);
-
内存说明
- 指针数组:首先它是一个数组,数组的元素都指向指针,也就是说该数组储存的是指针,数组占的内存大小(字节数)由数组本身决定。
- 数组指针:首先它是一个指针,指向一个数组的首地址,也就是说它只储存指向数组的一个地址,而在32位系统下一个地址永远都是只占4个字节,64位系统占8个字节。
-
数组指针的注意事项
int arr[5] = { 1, 2, 3, 4, 5}; char arr1[5] = { 1, 2, 3, 4, 5}; int (*p1)[5] = &arr; //错误示范——0 int (*p2)[5] = arr; //错误示范——1 int (*p3)[5] = arr1;
-
错误示范解释:
因为C语言中,=
的两侧数据必须是相同的,如果不同,则需要显示或者隐式的类型转换。
而数组指针的本质是一个指针,储存的是地址,该地址指向整个数组,而&arr 是指向整个数组的首地址,arr 是指数组第一个元素的地址,所以使用需加警惕。
第二个因为数组指针中的int
修饰的是指向数组的元素,而arr1
数组内的元素都是char
类型,类型不匹配,所以不可这样使用。