要完全区分一个函数,可以凭几个特征:一是返回值、二是函数名、三是参数类型与个数。前文提到函数重载时,返回值不作为特征来区分(即只有返回值不同的函数不视为重载函数,第二个视为错误声明)。本文要提到“函数类型”,您将发现函数名不作为特征。
引用:函数类型由其返回值类型及形参表确定,而与函数名无关。
之所以要提函数类型这个概念,是因为本文要弱化函数的名称了。原因很简单,有了指针就不用管它所指对象的名称了,也不能管。
要彻底理解指向函数的指针,我认为还得先回顾指向变量的指针:
int i;
int *p = &i;//声明指针p,p指向i
int j;
p = &j;//p指向j
p = 0;//p不指向任何变量,一般写作p = NULL;
以上代码中,p就是一个变量、一个指针变量,该指针可以指向特定类型的变量(本例中为int型),也可以不指向任何变量。那么,“指向函数的指针”也是一个变量、一个指针变量,该变量指向特定类型的函数,也可以不指向任何函数。
但是,函数与变量不同,变量只要一个关键词就可以表达它的类型,而函数要返回值和参数一起来表达它的类型。所以,在声明这样一个指针时,声明语句也就复杂一点了,下面对比这两种指针的声明:
int *p1;//声明一个指向变量的指针
int (*p2)(int);//声明一个指向函数的指针
以上两行的唯一区别就是第二行后面有一对括号,因为如上文所说,要表达一个函数的类型不能仅凭返回值(本例中为int),还得加上形参表(本例中为(int))。相信有这两行的对比,可以让程序员们消除对这种指针声明语句的恐惧。如果非要把类型说个明白,那么可以这样认为:
p1的类型为“int (*)”
p2的类型为“int (*)(int)”
理解了p2的类型,要理解用“typedef”来简化该声明语句就不难了。
typedef int (*cmpFcn)(int);//定义一个类型同义词
cmpFcn p3;//利用该同义词定义一个指向函数的指针