1. 指针数组
顾名思义,指针数组就是存放指针的数组。
下面是几个指针数组的例子。
int* arr[10]; // 数组拥有10个元素,每个元素是 int*
char* arr2[4]; // 4个char* 指针组成的数组
char** arr3[5]; // 5个二级指针组成的数组
指针数组是一个数组,存放的元素是指针。再看下面的例子。
int main()
{
int a = 10;
int b = 20;
int c = 'c';
int d = 'd';
int* arr1[2] = { &a, &b };
int* arr2[2] = { &c, &d };
char* arr3[3] = { "zhangsan", "lisi", "wangwu" };
// ret1,ret2 的值为多少?
int ret1 = sizeof(arr3);
int ret2 = strlen(arr);
return 0;
}
ret = 12,数组中三个元素为 char* 指针,所以 3*4 = 12。
ret2 = 随机值,首元素地址指向第一个元素 char* ,第一个元素为一个地址,strlen从这个地址值开始计算,直到 ‘\0’ 结束,所以是随机值。
指针数组中存放的是指针,而不是指针所指的内容。
2. 数组指针
一个指向数组的指针.
int main
{
int arr[10];
int *parr = arr; // int类型的指针
int(*p)[10]; // 指向十个整形元素组成数组的数组指针
(*p)[10] = &arr;
}
由这个例子我们还应该知道,数组的地址应该存放在数组指针里。
来看一个应用数组指针的例子。
//二维数组打印函数
void print(int (*arr)[4], int x, int y)
{
int i = 0;
for (i = 0; i < x; i++)
{
int j = 0;
for (j = 0; j < y; j++)
{
//printf("%2d ", arr[i][j]);
printf("%2d ", *(*(arr + i)+j));
/*
arr+i :第i行地址
*(arr+i):第i行数组名,又等于第i行首地址
*(arr+i)+j:第i行第j个元素地址
*(*(arr+i)+j):第i行第j个元素
*/
}
printf("\n");
}
}
int main()
{
int arr[3][4] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
print(arr, 3, 4);
}
掌握了数组指针之后,我们可以将以前很多的参数为一维数组,二维数组的代码,进行优化,有兴趣的同学们可以尝试一下。
3. 分辨指针数组和数组指针
数组指针和指针数组其实很好分辨,我们只用掌握一点即可,观察解引用操作符 ‘*’ 的位置即可。
因为 ‘*’ 的优先级比较低,所以它必须紧挨着对象才能起作用。
int *arr[10],’* ’ 优先级没有 [ ] 高,所以arr先是一个数组,然后才有 ‘*’ 的事,所以这是一个指针数组。
int (*arr)[10], 这时有了 ( ) 的帮忙,所以 arr 先与 ‘*’ 结合,所以arr首先是一个指针,然后 [ ] 才出场,所以这是一个数组指针。