开始
注意()和[]的优先级比*高。所以先会跟前者结合。
//指针函数:返回值是指针类型的函数。
int *func();
//他的返回值类型是int *
//----
//`函数指针`:指向函数的指针
int *(*pFunc)();
//指向原型为:int func()函数的指针
//`指针数组`:数组的每个元素都是指针类型
int *a[10];
//数组指针。元素10个
int (*a)[10];
函数指针和指针函数看起来都长的很像。到底怎么判断它是一个指针还是一个函数原型?
判别它到底是指针还是数组还是函数
前面说过。注意*
和()
的优先级不一样。从名称
开始看。根据它的结合。判断它属于哪种情况(函数
。指针
。数组
)。再细分
例如
int *a[3];
[]
优先级高。先结合。判定a是一个数组
。那么接下来就判断它元素类型了。也就是剩下的int *
,该数组的元素是指针类型,也就是int *
;
int (*a)[3];
a被括号()
包裹了。那么先和a结合。判定a是个指针
。再继续的话。就到了优先级高的[3]
。说明指针a指向
的是一个数组
。剩下就是数组元素的类型。int
,也就是a指向的数组的是 int xx[][3];
那么对于一个函数指针呢
首先找到它的名称p。看到(*p)可以确定p是一个指针
。然后跟这一块结合的是()。说明指向函数
,p是一个函数指针。最后一步看这个函数的返回值类型。也就是int
int (*p)();
写复杂的类型变量的步骤
1.确定变量名p(此处有口误,函数不是变量,应该说确定名称p,以下就不改过来了)
2.确定变量(名称)是函数、数组、还是指针
()[]的优先级比高。如果是指针且存在与前面的符号组合。必然有(p)。用括号括起来。让它先和*组合。则判断类型是指针类型。如果是数组或者函数则直接p[10]或者p()
3.如果是数组。判别顺序是
元素个数(多少维数组)->元素类型
比如说int *a[3]
。已经判断a[3]是个数组
了。用大A
代替它。则int *A
。用A代表数组整体。*和它结合。它是指针类型。剩下的int。说明它是int指针。那么整个结合起来就是a
是一个具有3个元素
的元素类型为
int *的 一维数组
4.如果判别为函数。那么顺序是
函数分为三部分组成
1.函数名
2.返回值
3.参数表
4.函数体(如果是声明的时候,并没有函数体,只是写出一个函数的原形,就好像下面这样的)
int *fun(int,int);
//这是一个函数
//fun先和()结合,参数有两个,类型均为int,把fun(int,int)替换成一个整体FUN
int *FUN;
//把FUN看做是函数的返回值,那么确定下FUN的类型,*FUN,它是个指针类型,
//int *FUN,说明他是int的指针类型,一级指针,也就是int *
可以用替代的方法去简化当前的复杂指针定义或者是函数声明等等,举个例子
int (*fun(int a,int (*b)(int) ))();
先看int a很明显是个形参了,所以,我们先去看fun
fun先和()结合,它应该是一个函数声明,参数表我们先不管他,把参数表的东西看成是ARG,一个整体,也就是int a,int (*b)(int)
,然后就成了
int (*fun(ARG))();
再细化,把函数和参数表看成一个整体FUN,也就是fun(ARG)
这部分,FUN可以看做是函数返回值的替代了,下一步就该判断返回值的类型
int (*FUN)();
这样看,FUN先跟*结合,说明FUN是一个指针,然后接着它跟()结合,说明这是一个函数指针,把(*FUN)
这部分用FUNB来替代,这样更容易看出,FUN指向函数的原形
int FUNB();
这样我们就找到了函数原形为int xx();
总结一下
int (*fun(int a,int (*b)(int) ))();
这是一个函数声明,它有两个参数,a
和b
,它其实可以写成(不要参数名称只写类型)
int ( *fun(int ,int (*)(int)) )();
这个函数的返回值是一个函数指针,这个指针指向的函数原形是int xx();