声明指向函数的指针:
void ToUpper (char *); // 把字符串转换为大写 void (*pf) (char *); // 指向函数的指针
第一对圆括号将运算符*和pf结合在一起,这意味着pf是一个指向函数的指针。这就使得(*pf)是一个函数,并使(char *)作为该函数的参量列表,void作为返回类型。创建这类声明最简单的方法是注意它用表达式(*Pf)代替函数名ToUpper。
根据运算符优先级的规则,第一个括号是必须的,省略括号会导致完全不同的解释:
void *pf (char *); // pf是返回一个指针的函数
有了函数指针后,可以把适当类型的函数的地址赋给它。在这种场合中,函数名可以用来表示函数的地址:
void ToUpper (char *); void ToLower (char *); int round (double); void (*Pf) (char *); pf = ToUpper; // 合法,ToUpper是函数ToUpper( )的地址 pf = ToLower; // 合法,ToLower是函数ToLower( )的地址 // pf = round; // 非法,round是错误类型的函数 // pf = ToLower(); // 非法,ToLower()不是地址
使用函数指针来访问函数。有两种逻辑上不一致的语法规则来实现这样的操作:
void ToUpper (char *); void (*pf) (char *); char mis[] = "Nina Metier"; (*pf) (mis); // 语法1 (pf (mis); // 语法2
为了保持与现有代码的兼容性,ANSI C把两者作为等价的形式全部接受。
函数指针最普遍的用法之一是作为函数的参数。例如:
void show (void (* fp) (char *), char * str) { (*fp) (str); // 把所选函数作用于str }
函数指针的数组
可以声明并初始化函数指针的数组:
typedef void (* V_FP_CHARP) (char *); V_FP_CHARP arpf[4] = {ToUpper, ToLower, Transpose, Dummy};
注意:存在“函数指针的数组”,但不存在“函数数组”
总结下使用函数名的四种方法:
- 定义函数
- 声明函数
- 调用函数
- 作为指针