指针数组
数组是一个存放相同类型数据的存储空间。我们先来看一下整型数组
int arr[5] = { 0 }; printf("%p\n", arr); printf("%p\n", arr + 1); printf("%p\n", &arr); printf("%p\n", &arr + 1);
结果如下:
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; }
解释:首先,要存储地址,就要求要是一个指针,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
指向函数指针的数组的指针是一个指针,这个指针指向一个数组,数组的元素都是函数指针。