指针数组
数组是一个存放相同类型数据的存储空间。我们先来看一下整型数组
int arr[5] = { 0 };
printf("%p\n", arr);
printf("%p\n", arr + 1);
printf("%p\n", &arr);
printf("%p\n", &arr + 1);
结果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/65d08193f63d91b4b2d02781abd629d9.png)
arr与&arr值一样,表示数组地址,但是+1之后就不一样了。
arr+1是第二个元素的地址。&arr+1是跳过了这个数组的所有元素的下一个地址。
总结:
数组名代表整个数组的时候有两种情况:
sizeof(数组名),表示整个数组。
&数组名,表示整个数组
那么什么是指针数组呢?
顾名思义,指针数组是一个数组,是存放指针的数组。请看下例
int *p[10];
[]的优先级高于 * ,p先和[ ] 结合说明是一个数组,int * 说明数组的每个元素是 int * 这个类型。
数组指针
数组指针,是一个指针,这个指针可以指向一个数组。先来看一个数组指针的定义以及初始化:
int (*pa)[10];
解释:pa先和*结合,说明pa是一个指针变量,指向一个大小为10个整型的数组。所以pa是一个指针,指向一个数组,叫做数组指针。注意:[ ]优先级高于*,必须要用( )确保pa先和 *结合。
int *(*pb)[5];
解释 : pb先和*结合,说明pa是一个指针变量,指向一个大小为10个整型指针的数组。
函数指针
函数指针是 一个指向函数的指针,其中存放函数的地址。
void test()
{
printf("hello");
}
int main()
{
printf("%p\n", test);
printf("%p\n", &test);
return 0;
}
输出的结果一样,都是test函数的地址。
那么怎么保存test的地址呢?
void test()
{
printf("hello");
}
int main()
{
printf("%p\n", test);
printf("%p\n", &test);
void(*pfun)() = test;
printf("%p\n", pfun);
return 0;
}
![](https://i-blog.csdnimg.cn/blog_migrate/9600fdbb1ae15a411fd5072f293444bd.png)
解释:首先,要存储地址,就要求要是一个指针,pfun先和* 结合,说明pfun是一个指针,指向的函数无参数,返回值类型为void。可以存放test函数的地址。
函数指针数组
把函数的地址存放到一个数组中,那这个数组就叫做 函数指针数组。先来看一下定义
int(*parr1[10])();
解释:parr先和 [ ] 结合,说明parr是个数组,数组中存放的是 int (*) ( )类型的函数指针。
如何使用它呢?void test()
{
printf("hello");
}
int main()
{
void(*pfunArr[5])( );//函数指针的数组
pfunArrpfunArr[0] = test;
//pfunArrpfunArr[0] = &test;一样的效果
return 0;
}
函数指针数组的指针
void(*pfunArr[5])(const char *str);
pfunArr[0] = test;
void(*(*ppfunArr)[10])(const char *) = &pfunArr;//指向函数指针的数组pfunArr的指针ppfunArr
指向函数指针的数组的指针是一个指针,这个指针指向一个数组,数组的元素都是函数指针。