下面的两个表达式:
float * g ( )
float (* f) ( )
所表达的意义是不一样的。
1. float * g ( ) 等同于 float * (g ( )),因为括号的优先级高于 *。
g ( ) 是一个函数,可以表示函数的返回值。* g ( ) 表示 g ( ) 是一个指针,即 g ( ) 的返回值是一个指针。* g ( ) 是一个 float 类型,所以 g ( ) 是一个指向返回值为float 类型数据的地址。
调用这个函数用
g ();
2. 在 float (* f) ( ) 中,(* f) ( ) 表示一个函数,这个函数的返回值为 float 类型。(* f) 表示函数标识,可以理解为函数的代码,所以 f 就是函数的指针,即函数代码的起始地址,函数从地址 f 开始执行。f 所指向的函数返回一个float 类型数据。
调用这个函数用
(* f) ();
函数指针示例1:
(float (* ) ( ))表示一个“返回值为浮点类型的函数的指针”的强制类型转换符,(float (* ) ( ))0 表示把 0 强制转换为“返回值为浮点类型的函数的指针”,即把 0 转换为一个函数的地址。
将常数 0 转换为“返回值为 void 类型的函数的指针” 可以这样写
(void (* ) ( ))0
用 fp 表示这个指针,(* fp) () 就表示这个指针指向的函数。调用这个函数可以用
(* fp) ();
这样
(* (void (* ) ( ))0 ) () ;
表示调用一个函数,函数的指针即起始地址为 0 (强制转换以后的地址)。
参见:C 缺陷与陷阱 (2.1)
函数指针示例2:
有了函数指针后,可以把适当类型的函数地址赋给它。
void ToUppler (char *);
void ToLower (char *);
int Round (double);
void (* pf) (char *);
pf = ToUpper; // 合法,可以把ToUppler看作函数地址
pf = ToLower; // 合法,可以把ToLower看作函数地址
pf = Round; // 不合法, 类型不匹配
pf = ToLower (); // 不合法,ToLower () 不是地址
指针函数调用:
char miss[]="Nina";
pf = ToUpper;
(* pf)(miss); // 可以这样调用
(pf)(miss);// 也可以这样调用
以函数指针为参数的函数:
void show (void (* p)(char *), char * str);
可以这样调用
show (ToUpper, miss);或
show (pf, miss);
使用typedef:
typedef void (* V_FP_CHARP) (char *);
定义了一个指针函数类型 V_FP_CHARP,该该函数的参数为 char *,返回值为void *。可以像使用其它类型一样使用 指针函数类型 V_FP_CHARP 。
void show (V_FP_CHARP fp, char *);
函数show以 V_FP_CHARP fp 和 char * 为参数。
V_FP_CHARP pfun;
定义一个V_FP_CHARP类型的变量。
pfun=ToUpper; 赋值
调用函数 show
show (pfun, miss);
参数传递函数的地址:
如果sqrt()是一个函数,那么
function1 (sqrt ) 参数传递的是函数sqrt()的起始地址;而
function1 (sqrt(4) ) 参数传递的是函数sqrt(4)的值。
参见:C Primer Plus (14.14)