1.指针数组
int* pArr[10]; //pArr是数组名,该数组存放了10个int*的元素
2.数组指针
int (*pA)[10]; //pA是一个指针,指向一个存放10个int元素的数组
3.函数指针
int (*pFun)(int,int); //这是一个函数指针,指向一个返回类型为int,两个参数为int的函数
4.有趣的代码
1)(*(void(*)())0)();
以上代码,看起来非常有意思,突破点就是0和void,若是熟悉函数指针类型的话,就会发现,void(*)()若是在*后面加上p,变成void(*p)(),很明显p就是一个函数指针,因此,void(*)()是一个函数指针类型,返回值void,参数为空,(void(*)())0又怎么解释呢?不知道大家记不记得强制类型转换的写法,如(int)10.1;当然这种由实型转换为整形会丢失精度,只保留10,我们此处不做考虑,回到正题,若是将10.1和0同等看待,(int)和(void(*)())同等看待,就会发现这是一个强制类型转换,0变成了一个函数指针,只是这个指针是0地址处的。若是能看到这里,那么后面的代码就简单了,首先对0地址处的函数指针进行解引用,得到什么?函数指针指向函数,解引用得到函数。再思考一个问题,函数是怎么调用的如:
int add(int x,int y)
我们要想使用它,很简单,就是add(5,6); 函数名加参数即可,若是无参函数呢?
void print()
直接写print(),前面说到(*(void(*)()0))就是一个函数了,那么它怎么调用呢?即在其后面加上(),
(*(void(*)()0))()调用,这句代码整体看下来就是一个无参函数调用,在0地址处的一个返回值为void无参函数的调用。
2)void(*singal(int,void(*)(int)))(int);
这句代码又该怎么看呢?在看这句代码前,我们首先要了解*的优先级和结合性,如int *p(int)和int (*p)(int)怎么看,第一个是一个函数声明,该函数返回值是int* 函数名为p 返回值为int,第二个是一个函数指针,指向一个返回值为int,参数为int的函数,因此singal(int,void(*)(int))优先一起看,那么还剩下什么?void(* )(int);这是函数指针啊,
void(*)(int) singal(int , void(*)(int));
这么看的话是不是有点明白了,当然上述写法是错误的,若是记得typedef的用法的话,可以用typedef void(*vfun_int)(int); 那么以上代码即为:
vfun_int singal(int,vfun_int);
这有点类似于(不是)数学里的换元,可以清晰知道其结构,看到这就会明白了,这是一个函数声明,singal是一个函数名,int,vfun_int是参数, vfun_int是返回类型。
3)void(*pArr[10])(int,void(*)(int));
首先看pArr,看它与*还是[]结合,很明显是pArr[10],这是一个数组,元素为void(*)(int,void(*)(int))类型,这是一个函数指针,那么pArr就是一个函数指针数组,有10个元素,元素类型为函数指针,其参数为int和返回值为void参数为int的函数指针,返回值为void。